mirror of
https://github.com/neovim/neovim.git
synced 2026-06-15 16:23:48 +00:00
backport fix(lsp): refresh codelens despite pending debounce #40177
Problem: When a server sends workspace/codeLens/refresh while an automatic codelens request is already scheduled, Nvim ignores the server refresh. This can leave rendered codelens text stale until another buffer edit triggers a new request. Solution: Cancel the pending automatic request and send the server-requested refresh immediately. This preserves request coalescing while giving explicit server refreshes priority. Co-authored-by: Tristan Knight <admin@snappeh.com>
This commit is contained in:
@@ -174,6 +174,14 @@ function Provider:automatic_request()
|
||||
end, 200)
|
||||
end
|
||||
|
||||
---@package
|
||||
---@param client_id integer
|
||||
---@param on_response function
|
||||
function Provider:refresh(client_id, on_response)
|
||||
self:reset_timer()
|
||||
self:request(client_id, on_response)
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param client vim.lsp.Client
|
||||
---@param unresolved_lens lsp.CodeLens
|
||||
@@ -484,15 +492,12 @@ function M.on_refresh(err, _, ctx)
|
||||
for bufnr, provider in pairs(Provider.active) do
|
||||
for client_id in pairs(provider.client_state) do
|
||||
if client_id == ctx.client_id then
|
||||
-- Do nothing if a request is already scheduled.
|
||||
if not provider.timer then
|
||||
provider:request(client_id, function()
|
||||
if api.nvim_buf_is_valid(bufnr) then
|
||||
provider.row_version = {}
|
||||
vim.api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
|
||||
end
|
||||
end)
|
||||
end
|
||||
provider:refresh(client_id, function()
|
||||
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
|
||||
end
|
||||
|
||||
@@ -306,6 +306,58 @@ describe('vim.lsp.codelens', function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('refreshes immediately and cancels a pending automatic refresh', function()
|
||||
exec_lua(function()
|
||||
local deferred
|
||||
local request_count = 0
|
||||
local defer_fn = vim.defer_fn
|
||||
local client = assert(vim.lsp.get_client_by_id(client_id))
|
||||
local request = client.request
|
||||
|
||||
--- @diagnostic disable-next-line: duplicate-set-field
|
||||
vim.defer_fn = function(callback)
|
||||
deferred = {
|
||||
callback = callback,
|
||||
closed = false,
|
||||
stopped = false,
|
||||
is_closing = function(self)
|
||||
return self.closed
|
||||
end,
|
||||
stop = function(self)
|
||||
self.stopped = true
|
||||
end,
|
||||
close = function(self)
|
||||
self.closed = true
|
||||
end,
|
||||
}
|
||||
return deferred
|
||||
end
|
||||
|
||||
client.request = function(self, method, ...)
|
||||
if method == 'textDocument/codeLens' then
|
||||
request_count = request_count + 1
|
||||
end
|
||||
return request(self, method, ...)
|
||||
end
|
||||
|
||||
vim.api.nvim_buf_set_lines(0, 0, 0, false, { '// changed' })
|
||||
assert(deferred, 'expected pending automatic codelens refresh')
|
||||
|
||||
vim.lsp.codelens.on_refresh(
|
||||
nil,
|
||||
nil,
|
||||
{ method = 'workspace/codeLens/refresh', client_id = client_id }
|
||||
)
|
||||
|
||||
vim.defer_fn = defer_fn
|
||||
client.request = request
|
||||
|
||||
assert(deferred.stopped, 'expected pending codelens refresh to stop')
|
||||
assert(deferred.closed, 'expected pending codelens refresh to close')
|
||||
assert(request_count == 1, 'expected exactly one immediate codelens refresh request')
|
||||
end)
|
||||
end)
|
||||
|
||||
it('ignores stale codeLens/resolve responses', function()
|
||||
clear_notrace()
|
||||
exec_lua(create_server_definition)
|
||||
|
||||
Reference in New Issue
Block a user