diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 5f007ee6ee..a362d9f8b3 100644 --- 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)