commit a702534c501f413b7d81461fbb141ff3bbc1c2d7
parent 672f6e60c165d72a58fd85ce57ed2989dcbcbd6a
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 3 Dec 2025 07:44:27 +0800
fix(lsp): close timer when client exits (#36795)
Also, don't start the timer at all when a previous shutdown failed, as
in this case a forced shutdown is used and no timer is needed.
This fixes most of the delays caused by #36750.
The delays caused by #36378 still seem to remain.
Diffstat:
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua
@@ -219,6 +219,9 @@ local all_clients = {}
--- Whether on-type formatting is enabled for this client.
--- @field _otf_enabled boolean?
---
+--- Timer for stop() with timeout.
+--- @field private _shutdown_timer uv.uv_timer_t?
+---
--- Track this so that we can escalate automatically if we've already tried a
--- graceful shutdown
--- @field private _graceful_shutdown_failed true?
@@ -882,12 +885,6 @@ end
---
--- @param force? boolean|integer
function Client:stop(force)
- if type(force) == 'number' then
- vim.defer_fn(function()
- self:stop(true)
- end, force)
- end
-
local rpc = self.rpc
if rpc.is_closing() then
return
@@ -902,6 +899,13 @@ function Client:stop(force)
return
end
+ if type(force) == 'number' then
+ self._shutdown_timer = vim.defer_fn(function()
+ self._shutdown_timer = nil
+ self:stop(true)
+ end, force)
+ end
+
-- Sending a signal after a process has exited is acceptable.
rpc.request('shutdown', nil, function(err, _)
if err == nil then
@@ -1309,6 +1313,11 @@ end
--- @param code integer) exit code of the process
--- @param signal integer the signal used to terminate (if any)
function Client:_on_exit(code, signal)
+ if self._shutdown_timer and not self._shutdown_timer:is_closing() then
+ self._shutdown_timer:close()
+ self._shutdown_timer = nil
+ end
+
vim.schedule(function()
for bufnr in pairs(self.attached_buffers) do
self:_on_detach(bufnr)