mirror of
https://github.com/neovim/neovim.git
synced 2026-01-06 19:39:53 +10:00
fix(lsp): :lsp restart restarts on client exit #37125
Problem: `:lsp restart` detects when a client has exited by using the `LspDetach` autocommand. This works correctly in common cases, but breaks when restarting a client which is not attached to any buffer. It also breaks if a client is detached in between `:lsp restart` and the actual stopping of the client. Solution: Move restart logic into `vim/lsp/client.lua`, so it can hook in to `_on_exit()`. The public `on_exit` callback cannot be used for this, as `:lsp restart` needs to ensure the restart only happens once, even if the command is run multiple times on the same client.
This commit is contained in:
@@ -908,6 +908,31 @@ function Client:stop(force)
|
||||
end)
|
||||
end
|
||||
|
||||
--- Stops a client, then starts a new client with the same config and attached
|
||||
--- buffers.
|
||||
---
|
||||
--- @param force? integer|boolean See [Client:stop()] for details.
|
||||
--- (default: `self.exit_timeout`)
|
||||
function Client:_restart(force)
|
||||
validate('force', force, { 'number', 'boolean' }, true)
|
||||
|
||||
self._handle_restart = function()
|
||||
--- @type integer[]
|
||||
local attached_buffers = vim.tbl_keys(self.attached_buffers)
|
||||
|
||||
vim.schedule(function()
|
||||
local new_client_id = lsp.start(self.config, { attach = false })
|
||||
if new_client_id then
|
||||
for _, buffer in ipairs(attached_buffers) do
|
||||
lsp.buf_attach_client(buffer, new_client_id)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
self:stop(force)
|
||||
end
|
||||
|
||||
--- Get options for a method that is registered dynamically.
|
||||
--- @param method vim.lsp.protocol.Method | vim.lsp.protocol.Method.Registration
|
||||
function Client:_supports_registration(method)
|
||||
@@ -1334,6 +1359,11 @@ function Client:_on_exit(code, signal)
|
||||
end
|
||||
end)
|
||||
|
||||
if self._handle_restart ~= nil then
|
||||
self._handle_restart()
|
||||
self._handle_restart = nil
|
||||
end
|
||||
|
||||
-- Schedule the deletion of the client object so that it exists in the execution of LspDetach
|
||||
-- autocommands
|
||||
vim.schedule(function()
|
||||
|
||||
Reference in New Issue
Block a user