fix(lsp): clear push diagnostics on detach #40634

Problem: when an LS client detaches from the buffer, only pull diagnostics
are cleared via capability framework. Push diagnostics remain stuck even
when client stops/restarts.

Solution: clear push diagnostics on client detach.

ref #33864
This commit is contained in:
Oleh Volynets
2026-07-08 18:00:21 +02:00
committed by GitHub
parent 089662d318
commit ef130902cf
2 changed files with 47 additions and 14 deletions

View File

@@ -1436,6 +1436,8 @@ function Client:_on_detach(bufnr)
end
end
vim.diagnostic.reset(vim.lsp.diagnostic.get_namespace(self.id, false), bufnr)
changetracking.reset_buf(self, bufnr)
self:_text_document_did_close_handler(bufnr)

View File

@@ -103,26 +103,26 @@ describe('vim.lsp.diagnostic', function()
describe('vim.lsp.diagnostic.on_publish_diagnostics', function()
before_each(function()
exec_lua(create_server_definition)
exec_lua(function()
client_id = assert(vim.lsp.start({
cmd_env = {
NVIM_LUA_NOTRACK = '1',
_G.requests = 0
_G.server = _G._create_server({
capabilities = {
diagnosticProvider = {},
},
cmd = {
vim.v.progpath,
'-es',
'-u',
'NONE',
'--headless',
},
offset_encoding = 'utf-16',
}, { attach = false }))
})
client_id = assert(vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd }))
end)
end)
after_each(function()
exec_lua(function()
vim.lsp.get_client_by_id(client_id):stop()
local client = vim.lsp.get_client_by_id(client_id)
if client then
client:stop()
end
vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false })
end)
end)
@@ -269,6 +269,37 @@ describe('vim.lsp.diagnostic', function()
eq(1, #before_delete)
eq(0, #after_delete)
end)
it('clears diagnostics when client is detached', function()
exec_lua(function()
vim.lsp.diagnostic.on_publish_diagnostics(nil, {
uri = fake_uri,
diagnostics = {
_G.make_error('Diagnostic', 0, 0, 0, 0),
},
}, { client_id = client_id })
end)
eq(
1,
exec_lua(function()
local ns = vim.lsp.diagnostic.get_namespace(client_id)
return #vim.diagnostic.get(diagnostic_bufnr, { namespace = ns })
end)
)
exec_lua(function()
vim.lsp.get_client_by_id(client_id):stop()
end)
eq(
0,
exec_lua(function()
local ns = vim.lsp.diagnostic.get_namespace(client_id)
return #vim.diagnostic.get(diagnostic_bufnr, { namespace = ns })
end)
)
end)
end)
describe('vim.lsp.diagnostic.on_diagnostic', function()
@@ -489,7 +520,7 @@ describe('vim.lsp.diagnostic', function()
eq(1, diagnostics[1].severity)
end)
it('clears diagnostics when client detaches', function()
it('clears pull diagnostics when client detaches', function()
exec_lua(function()
vim.lsp.diagnostic.on_diagnostic(nil, {
kind = 'full',