Why
When two LSP clients attach to different buffers, the second LspAttach event silently clears the cleanup handler for the first buffer, leaving reference-highlight autocmds permanently active on that buffer after its LSP detaches.
Current state
lua/config/plugins/specs/nvim-lspconfig.lua registers a LspDetach autocmd inside highlight_references_to_cursor_word_in_editor (line 88) using vim.api.nvim_create_augroup('lsp-detach', { clear = true }). The { clear = true } flag deletes all previously registered handlers in that group on every call. Since this function runs on every LspAttach event, each new LSP attachment silently removes the LspDetach cleanup registered by the previous attachment. If jsonls attaches to one buffer and lua_ls attaches to another, only the second buffer gets a working cleanup handler; when the first buffer's LSP detaches, the CursorHold and CursorMoved highlight autocmds are never cleared.
Ideal state
- The
LspDetach cleanup autocmd is registered once per buffer, not once per LspAttach event globally
- Each registration is scoped to the specific buffer (
buffer = args.buf) so clearing or re-registering for one buffer does not affect other buffers
- When any LSP client detaches from a buffer, that buffer's
CursorHold/CursorMoved reference-highlight autocmds are reliably removed
Starting points
lua/config/plugins/specs/nvim-lspconfig.lua line 88 — the per-attach lsp-detach augroup registration to restructure
- The enclosing
LspAttach autocmd callback — where the corrected, buffer-scoped registration should live
QA plan
- Open
lua/config/plugins/specs/nvim-lspconfig.lua — expect the LspDetach handler to be registered with buffer = args.buf so each buffer gets its own scoped cleanup, and confirm { clear = true } is not applied globally to the group on every attach
- Open two buffers with different LSP servers active (e.g. a
.lua file with lua_ls and a .json file with jsonls)
- Close or detach the
jsonls LSP from the .json buffer — expect cursor movement on the remaining .lua buffer to stop triggering stale JSON-related highlight calls (verify via :autocmd CursorHold)
Done when
Opening and closing multiple LSP-attached buffers leaves no orphaned CursorHold or CursorMoved autocmds from detached LSP clients in any buffer.
Why
When two LSP clients attach to different buffers, the second LspAttach event silently clears the cleanup handler for the first buffer, leaving reference-highlight autocmds permanently active on that buffer after its LSP detaches.
Current state
lua/config/plugins/specs/nvim-lspconfig.luaregisters aLspDetachautocmd insidehighlight_references_to_cursor_word_in_editor(line 88) usingvim.api.nvim_create_augroup('lsp-detach', { clear = true }). The{ clear = true }flag deletes all previously registered handlers in that group on every call. Since this function runs on everyLspAttachevent, each new LSP attachment silently removes theLspDetachcleanup registered by the previous attachment. Ifjsonlsattaches to one buffer andlua_lsattaches to another, only the second buffer gets a working cleanup handler; when the first buffer's LSP detaches, theCursorHoldandCursorMovedhighlight autocmds are never cleared.Ideal state
LspDetachcleanup autocmd is registered once per buffer, not once per LspAttach event globallybuffer = args.buf) so clearing or re-registering for one buffer does not affect other buffersCursorHold/CursorMovedreference-highlight autocmds are reliably removedStarting points
lua/config/plugins/specs/nvim-lspconfig.lualine 88 — the per-attachlsp-detachaugroup registration to restructureLspAttachautocmd callback — where the corrected, buffer-scoped registration should liveQA plan
lua/config/plugins/specs/nvim-lspconfig.lua— expect theLspDetachhandler to be registered withbuffer = args.bufso each buffer gets its own scoped cleanup, and confirm{ clear = true }is not applied globally to the group on every attach.luafile withlua_lsand a.jsonfile withjsonls)jsonlsLSP from the.jsonbuffer — expect cursor movement on the remaining.luabuffer to stop triggering stale JSON-related highlight calls (verify via:autocmd CursorHold)Done when
Opening and closing multiple LSP-attached buffers leaves no orphaned
CursorHoldorCursorMovedautocmds from detached LSP clients in any buffer.