From c15ac3d64cb41fb9da03d520a4d2bdbf8ba01c52 Mon Sep 17 00:00:00 2001 From: jdrouhard Date: Thu, 16 Jul 2026 12:08:47 -0500 Subject: [PATCH] fix(lsp): capability cleanup #40763 --- runtime/lua/vim/lsp/_capability.lua | 32 +++++++++++++++++++++-------- runtime/lua/vim/lsp/diagnostic.lua | 12 +---------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/runtime/lua/vim/lsp/_capability.lua b/runtime/lua/vim/lsp/_capability.lua index ea37d0b4be..208fcc72a7 100644 --- a/runtime/lua/vim/lsp/_capability.lua +++ b/runtime/lua/vim/lsp/_capability.lua @@ -18,7 +18,7 @@ local all_capabilities = {} --- Track each capability instance created per buffer ---@type table buffer -> list of active capability instances -local buf_capabilities = vim.defaulttable() +local buf_capabilities = {} -- Abstract base class (not instantiable directly). -- For each buffer that has at least one supported client attached, @@ -73,7 +73,12 @@ function M:new(bufnr) }) self.client_state = {} + if not buf_capabilities[bufnr] then + buf_capabilities[bufnr] = {} + end + table.insert(buf_capabilities[bufnr], self) + Class.active[bufnr] = self return self end @@ -111,24 +116,27 @@ function M:on_detach(client_id) self.client_state[client_id] = nil end ----@param name vim.lsp.capability.Name -local function make_enable_var(name) - return ('_lsp_enabled_%s'):format(name) -end - +--- Callback invoked when textDocument/didClose is sent for a client. ---@param client_id integer ---@diagnostic disable-next-line: unused-local function M:on_close(client_id) end +--- Callback invoked when textDocument/didChange or textDocument/didOpen is sent for a client. ---@param client_id integer ---@diagnostic disable-next-line: unused-local function M:on_change(client_id) end +--- Callback invoked on every redraw. ---@param topline integer ---@param botline integer ---@diagnostic disable-next-line: unused-local function M:on_win(topline, botline) end +---@param name vim.lsp.capability.Name +local function make_enable_var(name) + return ('_lsp_enabled_%s'):format(name) +end + --- Optional filters |kwargs|, ---@class vim.lsp.capability.enable.Filter ---@inlinedoc @@ -250,6 +258,10 @@ nvim_on('LspNotify', augroup, function(ev) local client_id = ev.data.client_id ---@type integer local bufnr = ev.buf + if not buf_capabilities[bufnr] then + return + end + for _, provider in ipairs(buf_capabilities[bufnr]) do if provider.client_state[client_id] then if ev.data.method == 'textDocument/didClose' then @@ -266,8 +278,12 @@ end) local namespace = api.nvim_create_namespace('nvim.lsp.capability') api.nvim_set_decoration_provider(namespace, { on_win = function(_, _, bufnr, topline, botline) - for _, capability in ipairs(buf_capabilities[bufnr]) do - capability:on_win(topline, botline) + if not buf_capabilities[bufnr] then + return + end + + for _, provider in ipairs(buf_capabilities[bufnr]) do + provider:on_win(topline, botline) end end, }) diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 5393e489e2..c683c07b89 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -353,17 +353,7 @@ end --- Refresh diagnostics, only if we have attached clients that support it ---@package ---@param client_id integer Client ID to refresh ----@param only_visible? boolean Whether to only refresh for the visible regions of the buffer (default: false) -function Diagnostics:refresh(client_id, only_visible) - if - only_visible - and vim.iter(api.nvim_list_wins()):all(function(window) - return api.nvim_win_get_buf(window) ~= self.bufnr - end) - then - return - end - +function Diagnostics:refresh(client_id) local client = vim.lsp.get_client_by_id(client_id) local method = 'textDocument/diagnostic'