mirror of
https://github.com/neovim/neovim.git
synced 2026-05-06 08:26:45 -04:00
fix(lsp): skip codelens refresh redraw for deleted buffer #39193
Problem:
After on_refresh() sends a textDocument/codeLens request, the buffer may
be deleted before the response arrives. The response callback then tries
to redraw that deleted buffer and raises Invalid buffer id error.
Solution:
Check buffer validity before redrawing.
AI-assisted: Codex
Co-authored-by: Yi Ming <ofseed@foxmail.com>
(cherry picked from commit 97caa88972)
This commit is contained in:
committed by
github-actions[bot]
parent
34cbfeca9c
commit
5907307662
@@ -487,8 +487,10 @@ function M.on_refresh(err, _, ctx)
|
||||
-- Do nothing if a request is already scheduled.
|
||||
if not provider.timer then
|
||||
provider:request(client_id, function()
|
||||
provider.row_version = {}
|
||||
vim.api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
|
||||
if api.nvim_buf_is_valid(bufnr) then
|
||||
provider.row_version = {}
|
||||
vim.api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -383,6 +383,85 @@ describe('vim.lsp.codelens', function()
|
||||
eq('', api.nvim_get_vvar('errmsg'))
|
||||
end)
|
||||
|
||||
it('ignores refresh responses for deleted buffer', function()
|
||||
clear_notrace()
|
||||
exec_lua(create_server_definition)
|
||||
|
||||
insert('line1\n')
|
||||
|
||||
exec_lua(function()
|
||||
local codelens_request_count = 0
|
||||
_G.refresh_response_sent = false
|
||||
_G.server = _G._create_server({
|
||||
capabilities = {
|
||||
codeLensProvider = {
|
||||
resolveProvider = true,
|
||||
},
|
||||
},
|
||||
handlers = {
|
||||
['textDocument/codeLens'] = function(_, _, callback)
|
||||
codelens_request_count = codelens_request_count + 1
|
||||
|
||||
local lenses = {
|
||||
{
|
||||
command = {
|
||||
arguments = {},
|
||||
command = 'dummy.command',
|
||||
title = 'Lens',
|
||||
},
|
||||
range = {
|
||||
['end'] = {
|
||||
character = 1,
|
||||
line = 0,
|
||||
},
|
||||
start = {
|
||||
character = 0,
|
||||
line = 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if codelens_request_count == 1 then
|
||||
callback(nil, lenses)
|
||||
else
|
||||
-- Delay the refresh response so the buffer is wiped before it arrives.
|
||||
vim.schedule(function()
|
||||
_G.refresh_response_sent = true
|
||||
callback(nil, lenses)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
local client_id = vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })
|
||||
vim.lsp.codelens.enable()
|
||||
|
||||
assert(
|
||||
vim.wait(1000, function()
|
||||
return #vim.lsp.codelens.get() > 0
|
||||
end),
|
||||
'timed out waiting for initial codelens response'
|
||||
)
|
||||
|
||||
vim.lsp.codelens.on_refresh(nil, nil, {
|
||||
method = 'workspace/codeLens/refresh',
|
||||
client_id = client_id,
|
||||
})
|
||||
vim.cmd.bwipeout({ bang = true })
|
||||
|
||||
assert(
|
||||
vim.wait(1000, function()
|
||||
return _G.refresh_response_sent
|
||||
end),
|
||||
'timed out waiting for refresh response'
|
||||
)
|
||||
end)
|
||||
|
||||
eq('', api.nvim_get_vvar('errmsg'))
|
||||
end)
|
||||
|
||||
it('clears extmarks beyond the bottom of the buffer', function()
|
||||
feed('12G4dd')
|
||||
screen:expect([[
|
||||
|
||||
Reference in New Issue
Block a user