nvim-lualine / lualine.nvim

A blazing fast and easy to configure neovim statusline plugin written in pure lua.
MIT License
6.03k stars 463 forks source link

Bug: slow close when using custom function #1145

Closed iameru closed 10 months ago

iameru commented 10 months ago

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

Sam-programs commented 10 months ago

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
iameru commented 10 months ago

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?

Sam-programs commented 10 months ago

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

MunifTanjim commented 10 months ago

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
iameru commented 10 months ago

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.

MunifTanjim commented 10 months ago

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

iameru commented 10 months ago

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

Sam-programs commented 10 months ago

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

bjorntrondsen commented 6 months ago

(For anyone else looking for a lualine plugin for copilot.vim)

I couldnt find a any information about the activation status of copilot in vim.lsp.get_active_clients({name = 'copilot'}), so I wrote a very simple status indicator for copilot.vim based on vim.g.copilot_enabled instead https://gist.github.com/bjorntrondsen/4ee91256fdc7fc625578137e669a4b63

I dont know much about Lua or nvim scripting. Maybe a "working.." status could be added as well.

image image