rebelot/heirline.nvim

Keyboard interrupt error

Closed this issue · 3 comments

For the past few weeks, heirline would sometimes crash without any errors when I leave insert mode.
This time I had the same problem, but with an error.
The crash happens quite often when I work in .vue or .ts files. At least 3 - 4 times per day (on good days).

E5108: Error executing lua ...site/pack/packer/opt/heirline.nvim/lua/heirline/init.lua:92: Keyboard interrupt                               
stack traceback:                                                                                                                            
        [C]: in function '__index'                                                                                                          
        ...site/pack/packer/opt/heirline.nvim/lua/heirline/init.lua:92: in function <...site/pack/packer/opt/heirline.nvim/lua/heirline/init
.lua:90>                                                                                                                                   
Press ENTER or type command to continue

What I tried already
When no error was thrown, I started to remove 1 component every time I got a crash.
First, I suspected nvim-cmp because it would also sometimes crash, but after some updates it never happened again.

Steps:
<C-c> to leave insert mode

What happens
Heirline crashes with the "Keyboard interrupt" error.
I'm still in insert mode.

What should happen
Leaving insert mode without crashing

Versions
All on latest
neovim: 0.8.0
heirline: 19cab76

Heirline Config

local conditions = require("heirline.conditions")
local utils = require("heirline.utils")

local Align = { provider = "%=" }
local Space = { provider = " " }

local FileIcon = {
  init = function(self)
    local filename = self.filename
    local extension = vim.fn.fnamemodify(filename, ":e")

    self.icon, self.icon_color = require("nvim-web-devicons").get_icon_color(filename, extension, { default = true })
  end,
  provider = function(self)
    return self.icon and (self.icon .. " ")
  end,
  hl = function(self)
    return { fg = self.icon_color }
  end
}

local FileName = {
  provider = function(self)
    local filename = vim.fn.fnamemodify(self.filename, ":t")
    if filename == "" then return "[No Name]" end

    return filename
  end,
  hl = utils.get_highlight("StatusbarFileName")
}

local FileFlag = {
  {
    provider = function() if vim.bo.modified then return "*" end end,
    hl = utils.get_highlight("StatusbarFileFlagModified")
  },
  Space,
  {
    provider = function() if (not vim.bo.modifiable) or vim.bo.readonly then return "" end end,
    hl = utils.get_highlight("StatusbarFileFlagReadonly")
  }
}

local File = {
  init = function(self)
    self.filename = vim.api.nvim_buf_get_name(0)
  end,
  FileIcon, Space, FileName, Space, FileFlag
}

local FileEncoding = {
  provider = function()
    return (vim.bo.fenc ~= "" and vim.bo.fenc) or vim.o.enc -- :h "enc"
  end,
  hl = utils.get_highlight("StatusbarFileEncoding")
}

local FileFormat = {
  provider = function()
    return vim.bo.fileformat
  end,
  hl = utils.get_highlight("StatusbarFileFormat")
}

local Git = {
  condition = conditions.is_git_repo,
  init = function(self)
    self.git = vim.b.gitsigns_status_dict or {}
  end,
  {
    provider = function(self)
      return "󰘬  " .. self.git.head or 'unknown'
    end,
    hl = utils.get_highlight("StatusbarGitBranch")
  },
  Space,
  {
    provider = function(self)
      local count = self.git.added or 0
      return count > 0 and "+" .. count
    end,
    hl = utils.get_highlight("StatusbarGitAdded")
  },
  Space,
  {
    provider = function(self)
      local count = self.git.changed or 0
      return count > 0 and "~" .. count
    end,
    hl = utils.get_highlight("StatusbarGitChanged")
  },
  Space,
  {
    provider = function(self)
      local count = self.git.removed or 0
      return count > 0 and "-" .. count
    end,
    hl = utils.get_highlight("StatusbarGitRemoved")
  }
}

local Diagnostics = {
  condition = conditions.has_diagnostics,
  static = {
    error_icon = vim.fn.sign_getdefined("DiagnosticSignError")[1].text,
    warn_icon = vim.fn.sign_getdefined("DiagnosticSignWarn")[1].text,
    info_icon = vim.fn.sign_getdefined("DiagnosticSignInfo")[1].text,
    hint_icon = vim.fn.sign_getdefined("DiagnosticSignHint")[1].text,
  },
  init = function(self)
    self.errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR })
    self.warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN })
    self.hints = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT })
    self.infos = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO })
  end,
  update = { "DiagnosticChanged", "BufEnter" },
  {
    provider = function(self)
      return self.errors > 0 and self.error_icon .. self.errors
    end,
    hl = utils.get_highlight("DiagnosticError")
  },
  Space,
  {
    provider = function(self)
      return self.warnings > 0 and self.warn_icon .. self.warnings
    end,
    hl = utils.get_highlight("DiagnosticWarn")
  },
  Space,
  {
    provider = function(self)
      return self.infos > 0 and self.info_icon .. self.infos
    end,
    hl = utils.get_highlight("DiagnosticInfo")
  },
  Space,
  {
    provider = function(self)
      return self.hints > 0 and self.hint_icon .. self.hints
    end,
    hl = utils.get_highlight("DiagnosticHint")
  }
}

local Debugger = {
  condition = function()
    return require("dap").session()
  end,
  provider = function()
    return "󰃤  " .. require("dap").status()
  end,
  hl = utils.get_highlight("StatusbarDebug")
}

local Ruler = {
  {
    provider = "%l:%c",
    hl = utils.get_highlight("StatusbarLineStat")
  },
  Space,
  {
    provider = "%p",
    hl = utils.get_highlight("StatusbarLinePercent")
  }
}

local InactiveStatusbar = {
  condition = function() return not conditions.is_active() end,
  File, Align
}

local DefaultStatusbar = {
  File, Space, Git, Align, Debugger, Align, Diagnostics, Space, Space, FileEncoding, Space, FileFormat, Space, Ruler
}

require("heirline").setup({
  fallthrough = false,
  hl = function()
    if conditions.is_active() then
      return utils.get_highlight("Statusbar")
    else
      return utils.get_highlight("StatusbarNC")
    end
  end,
  InactiveStatusbar, DefaultStatusbar
})

why would you quit insert mode with <C-c> instead of <esc> or <C-[>? <C-c> has the effect to not trigger InsertLeave, which might be a problem in some cases. I really wouldn't know how to fix this. I am also unable to reproduce. My guess is that some of your components is taking a long time to compute. Try opening a file where you experience a crash and run :lua require'heirline'.timeit().

for the moment, if you're happy with your muscle memory, you could do inoremap <c-c> <esc>.

You are right, I shouldn't use <C-c>, I also tried to get away since I had issues with LSP diagnostics not updating. Looks like I sometimes use it without being aware of.

I'll try to fix my muscle memory first and if I still get the issue, I will try looking into it.

After a few days working without <C-c> I had no issues anymore.