mirror of
https://github.com/neovim/neovim.git
synced 2025-12-17 20:05:38 +00:00
feat(lsp): support auto-force escalation in client stop #36430
(cherry picked from commit 02cd564896)
This commit is contained in:
@@ -1278,7 +1278,7 @@ Lua module: vim.lsp.client *lsp-client*
|
|||||||
See |Client:notify()|.
|
See |Client:notify()|.
|
||||||
• {cancel_request} (`fun(self: vim.lsp.Client, id: integer): boolean`)
|
• {cancel_request} (`fun(self: vim.lsp.Client, id: integer): boolean`)
|
||||||
See |Client:cancel_request()|.
|
See |Client:cancel_request()|.
|
||||||
• {stop} (`fun(self: vim.lsp.Client, force: boolean?)`)
|
• {stop} (`fun(self: vim.lsp.Client, force: boolean|integer?)`)
|
||||||
See |Client:stop()|.
|
See |Client:stop()|.
|
||||||
• {is_stopped} (`fun(self: vim.lsp.Client): boolean`) See
|
• {is_stopped} (`fun(self: vim.lsp.Client): boolean`) See
|
||||||
|Client:is_stopped()|.
|
|Client:is_stopped()|.
|
||||||
@@ -1531,8 +1531,14 @@ Client:stop({force}) *Client:stop()*
|
|||||||
you request to stop a client which has previously been requested to
|
you request to stop a client which has previously been requested to
|
||||||
shutdown, it will automatically escalate and force shutdown.
|
shutdown, it will automatically escalate and force shutdown.
|
||||||
|
|
||||||
|
If `force` is a number, it will be treated as the time in milliseconds to
|
||||||
|
wait before forcing the shutdown.
|
||||||
|
|
||||||
|
Note: Forcing shutdown while a server is busy writing out project or index
|
||||||
|
files can lead to file corruption.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {force} (`boolean?`)
|
• {force} (`boolean|integer?`)
|
||||||
|
|
||||||
Client:supports_method({method}, {bufnr}) *Client:supports_method()*
|
Client:supports_method({method}, {bufnr}) *Client:supports_method()*
|
||||||
Checks if a client supports a given method. Always returns true for
|
Checks if a client supports a given method. Always returns true for
|
||||||
|
|||||||
@@ -1208,42 +1208,8 @@ api.nvim_create_autocmd('VimLeavePre', {
|
|||||||
client:stop()
|
client:stop()
|
||||||
end
|
end
|
||||||
|
|
||||||
local timeouts = {} --- @type table<integer,integer>
|
for _, client in pairs(active_clients) do
|
||||||
local max_timeout = 0
|
client:stop(client.flags.exit_timeout)
|
||||||
local send_kill = false
|
|
||||||
|
|
||||||
for client_id, client in pairs(active_clients) do
|
|
||||||
local timeout = client.flags.exit_timeout
|
|
||||||
if timeout then
|
|
||||||
send_kill = true
|
|
||||||
timeouts[client_id] = timeout
|
|
||||||
max_timeout = math.max(timeout, max_timeout)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local poll_time = 50
|
|
||||||
|
|
||||||
local function check_clients_closed()
|
|
||||||
for client_id, timeout in pairs(timeouts) do
|
|
||||||
timeouts[client_id] = timeout - poll_time
|
|
||||||
end
|
|
||||||
|
|
||||||
for client_id, _ in pairs(active_clients) do
|
|
||||||
if timeouts[client_id] ~= nil and timeouts[client_id] > 0 then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
if send_kill then
|
|
||||||
if not vim.wait(max_timeout, check_clients_closed, poll_time) then
|
|
||||||
for client_id, client in pairs(active_clients) do
|
|
||||||
if timeouts[client_id] ~= nil then
|
|
||||||
client:stop(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -804,8 +804,20 @@ end
|
|||||||
--- you request to stop a client which has previously been requested to
|
--- you request to stop a client which has previously been requested to
|
||||||
--- shutdown, it will automatically escalate and force shutdown.
|
--- shutdown, it will automatically escalate and force shutdown.
|
||||||
---
|
---
|
||||||
--- @param force? boolean
|
--- If `force` is a number, it will be treated as the time in milliseconds to
|
||||||
|
--- wait before forcing the shutdown.
|
||||||
|
---
|
||||||
|
--- Note: Forcing shutdown while a server is busy writing out project or index
|
||||||
|
--- files can lead to file corruption.
|
||||||
|
---
|
||||||
|
--- @param force? boolean|integer
|
||||||
function Client:stop(force)
|
function Client:stop(force)
|
||||||
|
if type(force) == 'number' then
|
||||||
|
vim.defer_fn(function()
|
||||||
|
self:stop(true)
|
||||||
|
end, force)
|
||||||
|
end
|
||||||
|
|
||||||
local rpc = self.rpc
|
local rpc = self.rpc
|
||||||
if rpc.is_closing() then
|
if rpc.is_closing() then
|
||||||
return
|
return
|
||||||
@@ -825,7 +837,7 @@ function Client:stop(force)
|
|||||||
if err == nil then
|
if err == nil then
|
||||||
rpc.notify(ms.exit)
|
rpc.notify(ms.exit)
|
||||||
else
|
else
|
||||||
-- If there was an error in the shutdown request, then term to be safe.
|
-- If there was an error in the shutdown request, then terminate to be safe.
|
||||||
rpc.terminate()
|
rpc.terminate()
|
||||||
self._graceful_shutdown_failed = true
|
self._graceful_shutdown_failed = true
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user