mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
fix(lsp): detect if Client:request resolved synchronously #33624
Problem:
In cases when the (in-process) LSP server responds to the request
immediately and calls `notify_reply_callback` the request will still be
marked as pending, because the code assumes that the response will occur
asynchronously. Then the request will be pending forever, because it was
already set as "completed" before we even set it as "pending".
A workaround is to wrap `notify_replay_callback` in `vim.shedule` ([like
so](https://github.com/neovim/neovim/pull/24338#issuecomment-2809568617)]
but that seems counterintuitive.
Solution:
Handle this case in Client:request().
(cherry picked from commit 8315697449
)
This commit is contained in:

committed by
github-actions[bot]
![github-actions[bot]](/assets/img/avatar_default.png)
parent
32842b0ee3
commit
f184c562c5
@@ -678,6 +678,12 @@ function Client:request(method, params, handler, bufnr)
|
||||
bufnr = vim._resolve_bufnr(bufnr)
|
||||
local version = lsp.util.buf_versions[bufnr]
|
||||
log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr)
|
||||
|
||||
-- Detect if request resolved synchronously (only possible with in-process servers).
|
||||
local already_responded = false
|
||||
local request_registered = false
|
||||
|
||||
-- NOTE: rpc.request might call an in-process (Lua) server, thus may be synchronous.
|
||||
local success, request_id = self.rpc.request(method, params, function(err, result)
|
||||
handler(err, result, {
|
||||
method = method,
|
||||
@@ -688,11 +694,15 @@ function Client:request(method, params, handler, bufnr)
|
||||
})
|
||||
end, function(request_id)
|
||||
-- Called when the server sends a response to the request (including cancelled acknowledgment).
|
||||
self:_process_request(request_id, 'complete')
|
||||
if request_registered then
|
||||
self:_process_request(request_id, 'complete')
|
||||
end
|
||||
already_responded = true
|
||||
end)
|
||||
|
||||
if success and request_id then
|
||||
if success and request_id and not already_responded then
|
||||
self:_process_request(request_id, 'pending', bufnr, method)
|
||||
request_registered = true
|
||||
end
|
||||
|
||||
return success, request_id
|
||||
|
Reference in New Issue
Block a user