Closed onsails closed 3 years ago
Thanks for the report! Can you send the relevant snippet(s) of your config?
I suppose we need some sort of rate limiting, though I'm not entirely sure what policy that should use.
besides regular setup made just as instructed in readme, I have the following lualine config:
local lualine = require('lualine')
lualine.status()
local lsp_status = require('lsp-status');
local lspconfig = require('lspconfig');
lsp_status.register_progress()
local function lsp()
return require('lsp-status').status()
end
lualine.sections.lualine_c = { lsp }
lualine.theme = 'forest_night'
and rust-analyzer is setup this way:
lspconfig.rust_analyzer.setup({
capabilities = capabilities,
on_attach = on_attach,
settings = {
["rust-analyzer"] = {
cargo = {
loadOutDirsFromCheck = true,
allFeatures = true
},
procMacro = {
enable = true
},
checkOnSave = {
command = "clippy"
},
}
},
root_dir = util.root_pattern('Cargo.lock', '.git'),
})
I'm wondering if this has to do with how often lualine
evaluates the lsp
component. I haven't been able to reproduce the issue yet, but - looking through status
, diagnostics
, and messages
, I'm not sure where redundant work can be avoided. Those functions mostly just look through a table filled by a callback when message events come in. It's possible that the implementation could be optimized (e.g. table.insert
is used a lot and could be replaced, there are a few places where maybe we could skip some loops?), but I'm surprised that this would cause so severe an error if the component isn't being invoked too often.
Another alternative (and maybe the best option) would be to change the plugin to generate a statusline string on a fixed frequency, then make status
query this string. I'm not likely to get to this work anytime soon, but I'd happily review a PR for it.
Also, if you have a public repo I could use to reproduce this issue, that would be very helpful.
@wbthomason thank you for investigating it. As mentioned by @kid in https://github.com/neovim/nvim-lspconfig/issues/395 the issue also happens with vim-airline. Furthermore until I switched to neovim lsp I've been using vim-airline + coc, rust-analyzer status messages were smooth back then thanks to throttling/debounce implemented in coc I suppose.
I've managed to create a minimal reproducer. It requires cargo and rust-analyzer available in $PATH, starting command is in readme.
You can notice that the spinning rectangle is freezing and if you hold down l
key for example you will notice it's lagging.
Beautiful, thanks for the repo to reproduce the issue. I'll give it a go as soon as I have a chance.
I also get a little bit of lag for a moment each time right after I save, although that goes away quickly each time and doesn't come back until I save again. I'm using rust-analyzer and lightline.vim.
Edit: okay, it doesn't just happen when I save, it also happens when inserting lines and text. It's unfortunately pretty disruptive.
Sorry, I still have not had time to look into this in depth. I tried to reproduce it using @onsails's minimal repro setup, but can't - I don't see any lag.
At a guess, this is just happening because we update the statusline on every new message, and some statuslines take a long time to draw. It looks like coc-rust-analyzer
does eager updates too (https://github.com/fannheyward/coc-rust-analyzer/blob/ead54f58cef1275263fcf6a7281ce14a472c29ea/src/ctx.ts#L59-L60), so there must be something happening in coc.nvim
's StatusBarItem
type (or somewhere related) to avoid updating so frequently.
If anyone wants to take a stab at a PR for this, I'd be happy to help guide things from the lsp-status
end. I would suggest looking at coc
's StatusBarItem
code and replicating any debounce logic here.
@wbthomason thank you for investigating it. As mentioned by @kid in neovim/nvim-lspconfig#395 the issue also happens with vim-airline. Furthermore until I switched to neovim lsp I've been using vim-airline + coc, rust-analyzer status messages were smooth back then thanks to throttling/debounce implemented in coc I suppose.
I've managed to create a minimal reproducer. It requires cargo and rust-analyzer available in $PATH, starting command is in readme.
You can notice that the spinning rectangle is freezing and if you hold down
l
key for example you will notice it's lagging.
I had the lag before, but can not reproduce it with this test.
I want to propose an optimization. Instead of calculating the statusline text in statusline.status()
we calculate it in the lsp_handler
and set a buffer variable with the result of statusline.lsp_status()
. When we need to redraw the statusline we just return this variable. Also, I added a variable to check if we need to render the new statusline only if the text changed.
I created a draft PR with the changes #42 if you can please test if it improves the performances.
I'm not the original reporter, but I just wanted to chime in and say I tested your branch @joshuachp, and it does seem to solve the problem for me. I'll keep using it and see if that holds true long-term.
Edit: Unfortunately, after using it a bit more, I'm still seeing the same lag
I'm not the original reporter, but I just wanted to chime in and say I tested your branch @joshuachp, and it does seem to solve the problem for me. I'll keep using it and see if that holds true long-term.
Edit: Unfortunately, after using it a bit more, I'm still seeing the same lag
Thanks for testing, I think that in the case of rust-analyzer
we are hitting a limitation of neovim if we redraw on every update, it will always lag no matter what. I will try to limit the number of redraws with next commit.
Closed by #43 and #45
With
lsp_status.register_progress()
neovim lags on each typed character. Apparently it's happening due to lots of indexing progress messages from rust-analyzer. Also the lag is noticeable in process of initial indexing just after rust-analyzer server started inside a project.The details are here