aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
authortris203 <admin@snappeh.com>2026-03-16 16:19:52 +0000
committertris203 <admin@snappeh.com>2026-03-19 17:51:21 +0000
commit0cda0183451443df81aeeba077bd3b93fa620eb8 (patch)
treeba8db54ff474b8750af7e2a1c7ba333e1e680c6a /runtime/lua/vim
parent95dce376f330029b54af1f00310d26536c713f5c (diff)
downloadrneovim-0cda0183451443df81aeeba077bd3b93fa620eb8.tar.gz
rneovim-0cda0183451443df81aeeba077bd3b93fa620eb8.tar.bz2
rneovim-0cda0183451443df81aeeba077bd3b93fa620eb8.zip
fix(lsp/diagnostic): key resultId by client and identifier
Previously, resultId for diagnostics was keyed only by client_id, which could cause issues when multiple identifiers are used by the same client. This change introduces a composite key of client_id and identifier for client_result_id, ensuring correct tracking of diagnostic results per identifier. Updates all relevant logic to use the new keying scheme.
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua45
1 files changed, 28 insertions, 17 deletions
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 2d224722ea..1a17da9e03 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -15,7 +15,7 @@ local augroup = api.nvim_create_augroup('nvim.lsp.diagnostic', {})
---@class (private) vim.lsp.diagnostic.BufState
---@field pull_kind 'document'|'workspace'|'disabled' Whether diagnostics are being updated via document pull, workspace pull, or disabled.
----@field client_result_id table<integer, string?> Latest responded `resultId`
+---@field client_result_id table<string, string?> Latest responded `resultId`, keyed by `client_id.identifier`
---@type table<integer, vim.lsp.diagnostic.BufState>
local bufstates = {}
@@ -147,6 +147,13 @@ local function tags_vim_to_lsp(diagnostic)
return tags
end
+---@param client_id integer
+---@param identifier string|nil
+---@return string
+local function result_id_key(client_id, identifier)
+ return string.format('%d.%s', client_id, identifier or 'nil')
+end
+
--- Converts the input `vim.Diagnostic`s to LSP diagnostics.
--- @param diagnostics vim.Diagnostic[]
--- @return lsp.Diagnostic[]
@@ -281,14 +288,15 @@ function M.on_diagnostic(error, result, ctx)
local client_id = ctx.client_id
local bufnr = assert(ctx.bufnr)
local bufstate = bufstates[bufnr]
- bufstate.client_result_id[client_id] = result.resultId
+ ---@type lsp.DocumentDiagnosticParams
+ local params = ctx.params
+ local key = result_id_key(client_id, params.identifier)
+ bufstate.client_result_id[key] = result.resultId
if result.kind == 'unchanged' then
return
end
- ---@type lsp.DocumentDiagnosticParams
- local params = ctx.params
handle_diagnostics(params.textDocument.uri, client_id, result.items, params.identifier or true)
for uri, related_result in pairs(result.relatedDocuments or {}) do
@@ -304,7 +312,7 @@ function M.on_diagnostic(error, result, ctx)
or { pull_kind = 'document', client_result_id = {} }
bufstates[related_bufnr] = related_bufstate
- related_bufstate.client_result_id[client_id] = related_result.resultId
+ related_bufstate.client_result_id[key] = related_result.resultId
end
end
@@ -383,11 +391,12 @@ function M._refresh(bufnr, client_id, only_visible)
for _, client in ipairs(clients) do
---@param cap lsp.DiagnosticRegistrationOptions
client:_provider_foreach(method, function(cap)
+ local key = result_id_key(client.id, cap.identifier)
---@type lsp.DocumentDiagnosticParams
local params = {
identifier = cap.identifier,
textDocument = util.make_text_document_params(bufnr),
- previousResultId = bufstate.client_result_id[client.id],
+ previousResultId = bufstate.client_result_id[key],
}
client:request(method, params, nil, bufnr)
end)
@@ -481,19 +490,20 @@ end
--- Returns the result IDs from the reports provided by the given client.
--- @return lsp.PreviousResultId[]
-local function previous_result_ids(client_id)
+--- @param client_id integer
+--- @param identifier string|nil
+local function previous_result_ids(client_id, identifier)
local results = {} ---@type lsp.PreviousResultId[]
+ local key = result_id_key(client_id, identifier)
for bufnr, state in pairs(bufstates) do
if state.pull_kind ~= 'disabled' then
- for buf_client_id, result_id in pairs(state.client_result_id) do
- if buf_client_id == client_id then
- results[#results + 1] = {
- uri = vim.uri_from_bufnr(bufnr),
- value = result_id,
- }
- break
- end
+ local result_id = state.client_result_id[key]
+ if result_id then
+ results[#results + 1] = {
+ uri = vim.uri_from_bufnr(bufnr),
+ value = result_id,
+ }
end
end
end
@@ -535,7 +545,8 @@ function M._workspace_diagnostics(opts)
-- state if we're not pulling document diagnostics for this buffer.
if bufstates[bufnr].pull_kind == 'workspace' and report.kind == 'full' then
handle_diagnostics(report.uri, ctx.client_id, report.items, params.identifier or true)
- bufstates[bufnr].client_result_id[ctx.client_id] = report.resultId
+ local key = result_id_key(ctx.client_id, params.identifier)
+ bufstates[bufnr].client_result_id[key] = report.resultId
end
end
end
@@ -547,7 +558,7 @@ function M._workspace_diagnostics(opts)
--- @type lsp.WorkspaceDiagnosticParams
local params = {
identifier = cap.identifier,
- previousResultIds = previous_result_ids(client.id),
+ previousResultIds = previous_result_ids(client.id, cap.identifier),
}
client:request('workspace/diagnostic', params, handler)