nvim-lualine/lualine.nvim

Bug: slow close when using custom function

iameru opened this issue · 9 comments

I use a function isCopilotActive in different parts of vim, specifically a binding which triggers it for me.
Now I wanted to get feedback in lualine and wrote a small function for it.
When adding it to a section the startup time of nvim slows down by half a second and the shutdown time around 1 second. this is enormous compared to subjectively "instant" startup and shutdown without it. I am not sure why this is happening.

function copilotIsActive()
  local output = vim.api.nvim_command_output("Copilot status")
  if string.find(output, "^Copilot: Enabled and online") then
    return true
  else
    return false
  end
end

function lualine_copilot()
  if copilotIsActive() then
    return "🤖"
  else
    return ""
  end
end

-- lua config
    lualine_c = {'filename', lualine_copilot },

Expected behaviour

no noticeable impact on performance

Actual behaviour

very noticeable impact on performance

lualine components are called a lot u probably only want to check if copilot is active when a new buffer is added

local copilit_active = {}
local autocmd = vim.api.nvim_create_autocmd
autocmd({ "BufNew" }, {
   pattern = { "*" },
   callback = function(ev)
      vim.api.nvim_buf_call(ev.buf, function()
         local output = vim.api.nvim_command_output("Copilot status")
         if string.find(output, "^Copilot: Enabled and online") then
            copilit_active[ev.buf] = true
         else
            copilit_active[ev.buf] = false
         end
      end)
   end,
})

function copilotIsActive()
  local buf = vim.api.nvim_get_current_buf()
  if copilit_active[buf] then
    return true
  else
    return false
  end
end

thanks for the feedback.
Hm, no, I actually trigger it from time to time via hotkey per buffer and don't want to check on new buffer only.
Thanks for your help though.

Might be useful to have a way to control how often a lualine component gets called?

i don't think u can do it per component maybe copilot has an auto command for activation/deactivation, which copilot plugin are u using?
or u could update the status in the mappings

Copilot is just a LSP server. You can use LspAttach and LspDetach event to check for updates.

:Copilot status is a very expensive operation, it does a lot of things. Instead you can use #vim.lsp.get_clients({ bufnr = 0, name = 'copilot' }) > 0 to check if Copilot is attached to the current buffer.

local copilot_active = {}
local autocmd = vim.api.nvim_create_autocmd
autocmd({ "LspAttach", "LspDetach" }, {
   pattern = { "*" },
   callback = function(ev)
      copilot_active[ev.buf] = #vim.lsp.get_clients({ bufnr = ev.buf, name = 'copilot' }) > 0
   end,
})

function copilotIsActive()
  return copilot_active[vim.api.nvim_get_current_buf()] or false
end

Thank you for explaining and suggesting a better way to check for this. Thanks really appreciate it. Now I get hit by attempt to call field 'get_clients' (a nil value), this is probably because I am starting buffers with copilot disabled.

This is totally out of scope of this issue now though, so I am closing it. Thanks again @MunifTanjim, I now have an Idea on how to do this better.

Now I get hit by attempt to call field 'get_clients' (a nil value), this is probably because I am starting buffers with copilot disabled.

That is probably because you're using an older version of neovim. In older neovim there was a different function vim.lsp.buf_get_clients. @iameru

just for the curious:

nvim --version
NVIM v0.9.4

searching for get_clients reveals, in the deprecated section:

- *vim.lsp.buf_get_clients()*		Use |vim.lsp.get_active_clients()| with
					{buffer = bufnr} instead.

lsp.get_clients is not to be found. So using vim.lsp.get_active_clients() works somewhat and quickens this up a lot.

It still doesn't really work from a usability point of view as it doesn't change when for example deactivating it for the buffer again but I'll figure that out. Dive into lua is fun. Thanks again @MunifTanjim

Maybe using copilot#Enabled or the buffer variables copilot_enabled/copilot_disabled,has less overhead?