mirror of
https://github.com/neovim/neovim.git
synced 2026-08-31 03:13:48 +00:00
fix(lsp): avoid scheduling client deletion before LspNotify #37685
Problem: `Client.on_exit` runs `Client._on_detach` and the client removal logic within two separate `vim.schedule` sequentially. However, since `Client._on_detach` executes `LspNotify` inside `vim.schedule`, this causes `LspNotify` to be executed after the client removal, which is scheduled first. At that point, a valid `Client` can no longer be retrieved within the autocmd callback. Solution: Put the client deletion inside the `vim.schedule` call.
This commit is contained in:
@@ -1358,6 +1358,28 @@ function Client:_on_exit(code, signal)
|
|||||||
reset_defaults(bufnr)
|
reset_defaults(bufnr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Schedule the deletion of the client object
|
||||||
|
-- so that it exists in the execution of autocommands
|
||||||
|
vim.schedule(function()
|
||||||
|
all_clients[self.id] = nil
|
||||||
|
|
||||||
|
-- Client can be absent if executable starts, but initialize fails
|
||||||
|
-- init/attach won't have happened
|
||||||
|
if self then
|
||||||
|
changetracking.reset(self)
|
||||||
|
end
|
||||||
|
if code ~= 0 or (signal ~= 0 and signal ~= 15) then
|
||||||
|
local msg = string.format(
|
||||||
|
'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
|
||||||
|
self and self.name or 'unknown',
|
||||||
|
code,
|
||||||
|
signal,
|
||||||
|
log.get_filename()
|
||||||
|
)
|
||||||
|
vim.notify(msg, vim.log.levels.WARN)
|
||||||
|
end
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if self._handle_restart ~= nil then
|
if self._handle_restart ~= nil then
|
||||||
@@ -1365,28 +1387,6 @@ function Client:_on_exit(code, signal)
|
|||||||
self._handle_restart = nil
|
self._handle_restart = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Schedule the deletion of the client object so that it exists in the execution of LspDetach
|
|
||||||
-- autocommands
|
|
||||||
vim.schedule(function()
|
|
||||||
all_clients[self.id] = nil
|
|
||||||
|
|
||||||
-- Client can be absent if executable starts, but initialize fails
|
|
||||||
-- init/attach won't have happened
|
|
||||||
if self then
|
|
||||||
changetracking.reset(self)
|
|
||||||
end
|
|
||||||
if code ~= 0 or (signal ~= 0 and signal ~= 15) then
|
|
||||||
local msg = string.format(
|
|
||||||
'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
|
|
||||||
self and self.name or 'unknown',
|
|
||||||
code,
|
|
||||||
signal,
|
|
||||||
log.get_filename()
|
|
||||||
)
|
|
||||||
vim.notify(msg, vim.log.levels.WARN)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
self:_run_callbacks(
|
self:_run_callbacks(
|
||||||
self._on_exit_cbs,
|
self._on_exit_cbs,
|
||||||
lsp.client_errors.ON_EXIT_CALLBACK_ERROR,
|
lsp.client_errors.ON_EXIT_CALLBACK_ERROR,
|
||||||
|
|||||||
Reference in New Issue
Block a user