- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 637
Labels
bugSomething isn't workingSomething isn't working
Description
Description
When diagnostics.enable = true
and a filetype-generic LSP (e.g. typos-lsp
) is running, one may see flickering of diagnostics in the nvim-tree buffer/window.
On a more complex neovim setup than "Clean room replication" I also observed moderate to high CPU load.
A possible workaround for me was to add a check for vim.bo[bufnr].buflisted
in view.lua:491:is_buf_valid
. I am new to this stuff and not sure if this would be a valid solution.
Neovim version
NVIM v0.10.2
Build type: RelWithDebInfo
LuaJIT 2.1.1727870382
Operating system and version
Linux 6.11.3
Windows variant
nvim-tree version
master
Clean room replication
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
vim.cmd([[set runtimepath=$VIMRUNTIME]])
vim.cmd([[set packpath=/tmp/nvt-min/site]])
local package_root = "/tmp/nvt-min/site/pack"
local install_path = package_root .. "/packer/start/packer.nvim"
local function load_plugins()
require("packer").startup({
{
"wbthomason/packer.nvim",
"nvim-tree/nvim-tree.lua",
"nvim-tree/nvim-web-devicons",
-- ADD PLUGINS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
},
config = {
package_root = package_root,
compile_path = install_path .. "/plugin/packer_compiled.lua",
display = { non_interactive = true },
},
})
end
if vim.fn.isdirectory(install_path) == 0 then
print("Installing nvim-tree and dependencies.")
vim.fn.system({ "git", "clone", "--depth=1", "https://github.com/wbthomason/packer.nvim", install_path })
end
load_plugins()
require("packer").sync()
vim.cmd([[autocmd User PackerComplete ++once echo "Ready!" | lua setup()]])
vim.opt.termguicolors = true
vim.opt.cursorline = true
-- MODIFY NVIM-TREE SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
_G.setup = function()
require("nvim-tree").setup({
diagnostics = {
enable = true,
},
})
require("nvim-tree.api").tree.open()
end
-- UNCOMMENT this block for diagnostics issues, substituting pattern and cmd as appropriate.
-- Requires diagnostics.enable = true in setup.
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function()
-- please adjust path to `typos-lsp`
vim.lsp.start({ cmd = { "/home/des-b/.local/share/nvim/mason/bin/typos-lsp" } })
end,
})
Steps to reproduce
- Put a file with an invalid name:
som.txt
- Run neovim
Expected behavior
Diagnostic on som.txt
shown in nvim-tree should just show ''typos: som
should be some
"
Actual behavior
The diagnostic is shown but flickers every few ~100ms
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
alex-courtis commentedon Oct 13, 2024
I've seen a bit of flickering on and off for the diagnostic status with
som
,ede
and others in files.With the above setup you'll notice that there are multiple language servers running - it starts a new one whech every file is opened.
Open nvim-tree and two other files:
alex-courtis commentedon Oct 13, 2024
For other language servers, adding an identifying name is enough to result in the one instance being shared e.g. lua-language-server: wiki: Development: Native neovim Configuration
That doesn't seem to be the case for typos-lsp.
Using the "official" language server manager nvim-lspconfig did work nicely:
You'll need
typos-lsp
in your $PATHPlease let me know if that works and I'll convert this to a discussion.
alex-courtis commentedon Oct 13, 2024
alex-courtis commentedon Oct 13, 2024
#2956 nvt-min.lua fixed
Updated https://github.com/nvim-tree/nvim-tree.lua/wiki/Development
des-b commentedon Oct 15, 2024
You are right. With the
lspconfig
config as you suggested there is no flickering.I have to check my actual neovim config. (where I already use lspconfig with mason btw. 😅) There I observed the flickering as well. When I find the cause I will post it.
Sorry for the noise and thanks for the rapid response and the effort on nvim-tree!
alex-courtis commentedon Oct 18, 2024
No apologies needed; there are some issues here that we need to get to the bottom of.
des-b commentedon Oct 19, 2024
After a lot of stripping my configuration down I found the cause and the (already existing 🫣) solution. The underlying issue was "fixed" in neovim/nvim-lspconfig@b2c7317. Before this change a
FileType autocmd
is used to detect if a buffer should be lsp-attached. (normallylspconfig
usesBufReadPost
)With the following config I am able to reproduce the issue. Notice I have re-enabled
filetypes
. (also notice that this still not always causes flickering; see below the example)With the configuration above
lspconfig
attaches the buffer if both criteria are met:buftype
is notnofile
(checked inlspconfig/manager.lua:try_add()
)Now
nvim-tree.lua
setsBUFFER_OPTIONS
(create_buffer()
) in non-deterministic order. I played with this a little bit.buftype = "nofile"
beforefiletype = "NvimTree"
: no flickeringbuftype = "nofile"
afterfiletype = "NvimTree"
: always flickeringSo with the second order the behavior is reproducible since
typos-lsp
is always attached onnvim-tree
.Flickering itself is caused by lsp diagnostics I guess. When
typos-lsp
produces diagnostics innvim-tree
for invalid file names this will be detected as a buffer change which in turn will be checked bytypos-lsp
and this cycles forever.With this monkey-patched version of
nvim-tree
'sis_buf_valid
I can avoid flickering.I would like to be able to use
typos-lsp
onnvim-tree.lua
to detect typos in my file names. But I could also see that this would be fragile and might cause trouble in the future. (by settingbuftype
afterfiletype
innvim-tree
buffer set-up I would be able to)I am interested in your opinions on how to continue. At least it would make sense to ensure
BUFFER_OPTIONS
are set in a deterministic order. I could imagine there are other configs/plugins which would be troubled by this non-determinism.alex-courtis commentedon Oct 20, 2024
Wow, great find! We should do this regardless.
Would this deterministic order resolve all the above issues?
An array something like this. Guessed at a sensible order.
alex-courtis commentedon Oct 20, 2024
That is reasonable; we can safely ignore unlisted buffers.
view.is_buf_valid
doesn't make much sense: the name is misleading and it's only used in one place. Let's inline it into diagnostics so it is very clear what's happening.alex-courtis commentedon Oct 20, 2024
I'd be most grateful for a PR with both these changes; you're the best one to validate the solution ;)
fix(nvim-tree#2954): set buffer options in deterministic order
fix(nvim-tree#2954): redraw only for diagnostics if source buffer is …
6 remaining items
alex-courtis commentedon Nov 16, 2024
#2990 temporarily reverted this change.
alex-courtis commentedon Nov 17, 2024
Experimenting with
DiagnosticsChanged
event:data.diagnostics = nil
Event
data.bufnr
is the one and only buffer changed.data.diagnostics
contains the same list asfrom_nvim_lsp
vim.diagnostic.get
, however it is only for the one bufnr.It appears that we can use the events themselves to determine the state for each node, rather than enumerating. We can detect a delta, and do nothing if there is no delta.
Simplest Approach
When an event is received, set
diag_status
on the node, for the maximum severity. Note whether a change occurred.On a change, a debounced update will be scheduled, however that will only be a render, top show the new
diag_status
.Events are synchronous and very unlikely to become asynchronous as a lot of plugins would break.
Performant Alternative
Node lookup by path is expensive.
Maintain a cache of buffer names to severities and map them to the node
diag_status
only when a change occurs.fix(#2954): use LSP diagnostic data deltas from events instead of a f…
fix(#2954): use LSP diagnostic data deltas from events instead of a f…
fix(#2954): more efficient LSP updates, increase diagnostics.debounce…