feat(lsp): support dynamic registration for diagnostics (#36841)

This commit is contained in:
Tristan Knight
2025-12-06 23:55:07 +00:00
committed by GitHub
parent 9e9cdcaa18
commit 0f3e3c87b7
5 changed files with 47 additions and 5 deletions

View File

@@ -284,6 +284,7 @@ LSP
• |Client:stop()| now uses the `Client.exit_timeout` field to control the default of `force`.
• Support for `workspace/diagnostic/refresh`:
https://microsoft.github.io/language-server-protocol/specification/#diagnostic_refresh
- Support for dynamic registration for `textDocument/diagnostic`
LUA

View File

@@ -358,7 +358,7 @@ end
---@param bufnr integer buffer number
---@param client_id? integer Client ID to refresh (default: all clients)
---@param only_visible? boolean Whether to only refresh for the visible regions of the buffer (default: false)
local function refresh(bufnr, client_id, only_visible)
function M._refresh(bufnr, client_id, only_visible)
if
only_visible
and vim.iter(api.nvim_list_wins()):all(function(window)
@@ -407,7 +407,7 @@ function M.on_refresh(err, _, ctx)
else
for bufnr in pairs(client.attached_buffers or {}) do
if bufstates[bufnr] and bufstates[bufnr].pull_kind == 'document' then
refresh(bufnr)
M._refresh(bufnr)
end
end
end
@@ -442,7 +442,7 @@ function M._enable(bufnr)
end
if bufstates[bufnr] and bufstates[bufnr].pull_kind == 'document' then
local client_id = opts.data.client_id --- @type integer?
refresh(bufnr, client_id, true)
M._refresh(bufnr, client_id, true)
end
end,
group = augroup,
@@ -451,7 +451,7 @@ function M._enable(bufnr)
api.nvim_buf_attach(bufnr, false, {
on_reload = function()
if bufstates[bufnr] and bufstates[bufnr].pull_kind == 'document' then
refresh(bufnr)
M._refresh(bufnr)
end
end,
on_detach = function()

View File

@@ -158,6 +158,11 @@ RSC['client/registerCapability'] = function(_, params, ctx)
end
end
end
if reg.method == 'textDocument/diagnostic' then
for bufnr in pairs(client.attached_buffers) do
vim.lsp.diagnostic._refresh(bufnr, client.id)
end
end
end
return vim.NIL
end

View File

@@ -352,7 +352,7 @@ function protocol.make_client_capabilities()
},
textDocument = {
diagnostic = {
dynamicRegistration = false,
dynamicRegistration = true,
tagSupport = {
valueSet = get_value_set(constants.DiagnosticTag),
},

View File

@@ -498,6 +498,42 @@ describe('vim.lsp.diagnostic', function()
)
end)
it('supports dynamic registration', function()
exec_lua(create_server_definition)
exec_lua(function()
_G.server2 = _G._create_server({
diagnosticProvider = {
documentSelector = vim.NIL,
},
handlers = {
['textDocument/diagnostic'] = function(_, _, callback)
callback(nil, {
kind = 'full',
items = {
_G.make_error('Dynamic Diagnostic', 4, 4, 4, 4),
},
})
end,
},
})
local client_id2 = assert(vim.lsp.start({ name = 'dummy2', cmd = _G.server2.cmd }))
vim.lsp.handlers['client/registerCapability'](nil, {
registrations = {
{ id = 'diagnostic', method = 'textDocument/diagnostic' },
},
}, { client_id = client_id2, method = 'client/registerCapability' })
end)
eq(
1,
exec_lua(function()
return #vim.diagnostic.get(diagnostic_bufnr)
end)
)
end)
it('requests with the `previousResultId`', function()
-- Full reports
eq(