From 5c4b64aae59d162cf88d78760f9eb98699fb98f9 Mon Sep 17 00:00:00 2001 From: phanium <91544758+phanen@users.noreply.github.com> Date: Sun, 15 Feb 2026 20:33:49 +0800 Subject: [PATCH] fix(lsp): wait for exit_timeout on quit #37597 Problem: When quitting Nvim, LSP servers will not be force-stopped, even if ClientConfig.exit_timeout is set to an integer. pkill emmylua_ls; VIMRUNTIME=runtime/ nvim --clean -u repro.lua repro.lua ; waitpid $(pgrep emmylua_ls) vim.lsp.config('foo', { cmd = { 'emmylua_ls' }, exit_timeout = 1000 }) vim.lsp.enable('foo') vim.defer_fn(vim.cmd.quit, 500) Solution: On VimExit, wait up to `exit_timeout:integer` milliseconds for servers to exit. Do this with an explicit `vim.wait()`, because the actual force-stop is deferred, and won't be attempted if Nvim exits before then. Co-authored-by: Justin M. Keyes --- runtime/lua/vim/lsp.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 682f222e6c..8b2d3dc0ad 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1132,9 +1132,25 @@ api.nvim_create_autocmd('VimLeavePre', { local active_clients = lsp.get_clients() log.info('exit_handler', active_clients) + local max_timeout = 0 for _, client in pairs(active_clients) do + max_timeout = math.max(max_timeout, tonumber(client.exit_timeout) or 0) client:stop(client.exit_timeout) end + if max_timeout > 10 then + api.nvim_echo({ + { + string.format('Waiting %ss for lsp exit (Press Ctrl-C to force exit)', max_timeout / 1e3), + 'WarningMsg', + }, + }, true, {}) + end + + vim.wait(max_timeout, function() + return vim.iter(active_clients):all(function(client) + return client.rpc.is_closing() + end) + end) end, })