mirror of
https://github.com/neovim/neovim.git
synced 2026-04-01 05:12:02 +00:00
fix(lsp): ignore stale codelens resolve responses (#38153)
This commit is contained in:
@@ -186,20 +186,26 @@ function Provider:resolve(client, unresolved_lens)
|
||||
end
|
||||
|
||||
local row = unresolved_lens.range.start.line
|
||||
local lenses = assert(state.row_lenses[row])
|
||||
for i, lens in ipairs(lenses) do
|
||||
if lens == unresolved_lens then
|
||||
lenses[i] = resolved_lens
|
||||
end
|
||||
local lenses = state.row_lenses[row]
|
||||
-- A newer textDocument/codeLens response can replace row_lenses while resolve is in flight.
|
||||
if not lenses then
|
||||
return
|
||||
end
|
||||
|
||||
self.row_version[row] = nil
|
||||
api.nvim__redraw({
|
||||
buf = self.bufnr,
|
||||
range = { row, row + 1 },
|
||||
valid = true,
|
||||
flush = false,
|
||||
})
|
||||
for i, lens in ipairs(lenses) do
|
||||
-- Only apply if this exact unresolved lens still exists; otherwise response is stale.
|
||||
if lens == unresolved_lens then
|
||||
lenses[i] = resolved_lens
|
||||
self.row_version[row] = nil
|
||||
api.nvim__redraw({
|
||||
buf = self.bufnr,
|
||||
range = { row, row + 1 },
|
||||
valid = true,
|
||||
flush = false,
|
||||
})
|
||||
return
|
||||
end
|
||||
end
|
||||
end, self.bufnr)
|
||||
end
|
||||
|
||||
|
||||
@@ -305,6 +305,83 @@ describe('vim.lsp.codelens', function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('ignores stale codeLens/resolve responses', function()
|
||||
clear_notrace()
|
||||
exec_lua(create_server_definition)
|
||||
|
||||
insert('line1\nline2\n')
|
||||
|
||||
exec_lua(function()
|
||||
local codelens_request_count = 0
|
||||
_G.stale_resolve_sent = false
|
||||
_G.server = _G._create_server({
|
||||
capabilities = {
|
||||
codeLensProvider = {
|
||||
resolveProvider = true,
|
||||
},
|
||||
},
|
||||
handlers = {
|
||||
['textDocument/codeLens'] = function(_, _, callback)
|
||||
codelens_request_count = codelens_request_count + 1
|
||||
if codelens_request_count == 1 then
|
||||
callback(nil, {
|
||||
{
|
||||
range = {
|
||||
['end'] = {
|
||||
character = 1,
|
||||
line = 0,
|
||||
},
|
||||
start = {
|
||||
character = 0,
|
||||
line = 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
else
|
||||
callback(nil, {})
|
||||
end
|
||||
end,
|
||||
['codeLens/resolve'] = function(_, lens, callback)
|
||||
vim.defer_fn(function()
|
||||
_G.stale_resolve_sent = true
|
||||
callback(nil, {
|
||||
command = {
|
||||
arguments = {},
|
||||
command = 'dummy.command',
|
||||
title = 'resolved',
|
||||
},
|
||||
range = lens.range,
|
||||
})
|
||||
end, 100)
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
local stale_client_id = vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })
|
||||
vim.lsp.codelens.enable()
|
||||
vim.wait(1000, function()
|
||||
return #vim.lsp.codelens.get() > 0
|
||||
end)
|
||||
|
||||
vim.api.nvim__redraw({ flush = true })
|
||||
|
||||
vim.lsp.codelens.on_refresh(nil, nil, {
|
||||
method = 'workspace/codeLens/refresh',
|
||||
client_id = stale_client_id,
|
||||
})
|
||||
|
||||
assert(
|
||||
vim.wait(1000, function()
|
||||
return _G.stale_resolve_sent
|
||||
end),
|
||||
'timed out waiting for stale resolve response'
|
||||
)
|
||||
end)
|
||||
|
||||
eq('', api.nvim_get_vvar('errmsg'))
|
||||
end)
|
||||
|
||||
it('clears extmarks beyond the bottom of the buffer', function()
|
||||
feed('13G4dd')
|
||||
screen:expect([[
|
||||
|
||||
Reference in New Issue
Block a user