refactor(lsp): convert diagnostics to capability framework #40433

Problem:
Diagnostic tracking used a separate bufstates table and manual
LspDetach/LspNotify autocmd management via _enable()/_refresh(),
duplicating the lifecycle logic already provided by the Capability
framework. This caused inconsistencies in how client attach/detach and
buffer teardown were handled compared to other LSP features.

Solution:
Replace the ad-hoc bufstate tracking and _enable/_refresh pattern in
vim.lsp.diagnostic with a proper Diagnostics subclass of Capability.
This cleans up a few random places in the main lsp module and client
module that were poking the diagnostics. It also fixes some pre-existing
bugs and inconsistencies that were discovered:

- Refresh diagnostics immediately on attach instead of lazily by the
  first didOpen/didChange notification
- Fix Capability.active lookup in M.enable() to key by it_bufnr instead
  of the filter bufnr
- Set lsp defaults before calling the _text_document_did_open_handler in
  Client:on_attach() so defaults are there before any lsp notification
  occurs
- Log (and return early) on any error from a diagnostic request result
  instead of only returning early for server cancelled errors
This commit is contained in:
jdrouhard
2026-06-26 13:41:26 -05:00
committed by GitHub
parent 85718f9874
commit c98c93fcf8
7 changed files with 142 additions and 136 deletions

View File

@@ -554,11 +554,12 @@ function Client:initialize()
end
-- HACK: Capability modules must be loaded
require('vim.lsp.semantic_tokens')
require('vim.lsp._folding_range')
require('vim.lsp.inline_completion')
require('vim.lsp.diagnostic')
require('vim.lsp.document_color')
require('vim.lsp.inline_completion')
require('vim.lsp.linked_editing_range')
require('vim.lsp.semantic_tokens')
local init_params = {
-- The process Id of the parent process that started the server. Is null if
@@ -1187,10 +1188,10 @@ end
--- Useful for buffer-local setup.
--- @param bufnr integer Buffer number
function Client:on_attach(bufnr)
self:_text_document_did_open_handler(bufnr)
lsp._set_defaults(self, bufnr)
self:_text_document_did_open_handler(bufnr)
api.nvim_exec_autocmds('LspAttach', {
buf = bufnr,
modeline = false,
@@ -1439,9 +1440,6 @@ function Client:_on_detach(bufnr)
self:_text_document_did_close_handler(bufnr)
self.attached_buffers[bufnr] = nil
local namespace = lsp.diagnostic.get_namespace(self.id)
vim.diagnostic.reset(namespace, bufnr)
end
--- Reset defaults set by `set_defaults`.