Skip to content

Commit 6ab1cce

Browse files
committed
feat(LspconfigServerLifeCycle): add configuration option; add docs; disable by default
1 parent 162e479 commit 6ab1cce

File tree

3 files changed

+82
-51
lines changed

3 files changed

+82
-51
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ See [server_configurations.md](doc/server_configurations.md) (`:help lspconfig-a
3939
nvim-lspconfig does not set keybindings or enable completion by default. The following example configuration provides suggested keymaps for the most commonly used language server functions, and manually triggered completion with omnifunc (\<c-x\>\<c-o\>).
4040

4141
```lua
42+
-- Uncomment to automatically start/stop servers when nvim is idle (non-focused)
43+
-- See :h lspconfig-lifecycle for details
44+
-- vim.g.lspconfigServerLifeCycle = { timeout = 1000 * 60 * 30 }
45+
4246
-- Setup language servers.
4347
local lspconfig = require('lspconfig')
4448
lspconfig.pyright.setup {}

doc/lspconfig.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,28 @@ contained in `:LspInfo`:
472472
- `:LspRestart <client_id>` restarts the client with the given client id, and
473473
will attempt to reattach to all previously attached buffers.
474474

475+
==============================================================================
476+
SERVER LIFECYCLE MANAGEMENT *lspconfig-lifecycle*
477+
478+
`lspconfig` may automatically stop or restart workspace LSP servers by using
479+
`:LspStart` / `:LspStop` commands. When `nvim` loses focus it will automatically
480+
stop buffer-bound LSP server upon clearing timeout threshold and restart
481+
otherwise.
482+
483+
Disabled by default. To turn it on set the following global config option.
484+
Make sure it's set before |load-plugins| cycle and any |lspconfig-setup|.
485+
486+
>
487+
-- Table is expected
488+
vim.g.lspconfigServerLifeCycle = {
489+
-- ms before server is stopped (30 minutes by default)
490+
timeout = 1000 * 60 * 30
491+
}
492+
...
493+
local lspconfig = require('lspconfig')
494+
....
495+
496+
475497
==============================================================================
476498
EXAMPLE KEYBINDINGS *lspconfig-keybindings*
477499

plugin/lspconfig.lua

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ end
6161
-- Called from plugin/lspconfig.vim because it requires knowing that the last
6262
-- script in scriptnames to be executed is lspconfig.
6363
api.nvim_create_user_command('LspInfo', function()
64-
require 'lspconfig.ui.lspinfo'()
64+
require 'lspconfig.ui.lspinfo' ()
6565
end, {
6666
desc = 'Displays attached, active, and configured language servers',
6767
})
@@ -151,53 +151,58 @@ end, {
151151
desc = 'Opens the Nvim LSP client log.',
152152
})
153153

154-
--- Start/stop servers when nvim session looses focus and restart them on demand.
155-
-- This features is motivated by the fact that some servers may gain serious
156-
-- memory footprint and may incur performance issues. Added on May 12, 2023
157-
vim.api.nvim_create_augroup('LspconfigServerLifeCycle', { clear = true })
158-
vim.api.nvim_create_autocmd({
159-
'FocusGained',
160-
}, {
161-
pattern = '*',
162-
group = 'LspconfigServerLifeCycle',
163-
desc = 'Lspconfig: restart halted lsp servers for given',
164-
callback = function()
165-
if _G.nvimLspconfigTimer then
166-
_G.nvimLspconfigTimer:stop()
167-
_G.nvimLspconfigTimer:close()
168-
_G.nvimLspconfigTimer = nil
169-
end
170-
if #vim.lsp.get_active_clients() <= 1 then
171-
vim.cmd 'LspStart'
172-
end
173-
end,
174-
})
175-
176-
vim.api.nvim_create_autocmd({
177-
'FocusLost',
178-
}, {
179-
pattern = '*',
180-
group = 'LspconfigServerLifeCycle',
181-
desc = 'Lspconfig: halt lsp servers when focus is lost',
182-
callback = function()
183-
if not _G.nvimLspconfigTimer and #vim.lsp.get_active_clients() > 0 then
184-
local timeout = 1000 * 60 * 5 -- 5 minutes
185-
_G.nvimLspconfigTimer = vim.loop.new_timer()
186-
_G.nvimLspconfigTimer:start(
187-
timeout,
188-
0,
189-
vim.schedule_wrap(function()
190-
local activeServers = #vim.lsp.get_active_clients()
191-
vim.cmd 'LspStop'
192-
vim.notify(
193-
('[lspconfig]: nvim has lost focus, stop current language servers. Number of servers left: %s'):format(
194-
activeServers
195-
),
196-
vim.log.levels.INFO
197-
)
198-
_G.nvimLspconfigTimer = nil
199-
end)
200-
)
201-
end
202-
end,
203-
})
154+
if vim.g.lspconfigServerLifeCycle and type(vim.g.lspconfigServerLifeCycle) == 'table' then
155+
local defaultTimeOut = 1000 * 60 * 30 -- 30 minutes
156+
vim.g.lspconfigServerLifeCycle.timeout = vim.g.lspconfigServerLifeCycle.timeout or defaultTimeOut
157+
158+
--- Start/stop servers when nvim session looses focus and restart them on demand.
159+
-- This features is motivated by the fact that some servers may gain serious
160+
-- memory footprint and may incur performance issues. Added on May 12, 2023
161+
vim.api.nvim_create_augroup('lspconfigServerLifeCycle', { clear = true })
162+
vim.api.nvim_create_autocmd({
163+
'FocusGained',
164+
}, {
165+
pattern = '*',
166+
group = 'lspconfigServerLifeCycle',
167+
desc = 'Lspconfig: restart halted lsp servers for given',
168+
callback = function()
169+
if _G.nvimLspconfigTimer then
170+
_G.nvimLspconfigTimer:stop()
171+
_G.nvimLspconfigTimer:close()
172+
_G.nvimLspconfigTimer = nil
173+
end
174+
if #vim.lsp.get_active_clients() <= 1 then
175+
vim.cmd 'LspStart'
176+
end
177+
end,
178+
})
179+
180+
vim.api.nvim_create_autocmd({
181+
'FocusLost',
182+
}, {
183+
pattern = '*',
184+
group = 'lspconfigServerLifeCycle',
185+
desc = 'Lspconfig: halt lsp servers when focus is lost',
186+
callback = function()
187+
if not _G.nvimLspconfigTimer and #vim.lsp.get_active_clients() > 0 then
188+
local timeout = vim.g.lspconfigServerLifeCycle.timeout
189+
_G.nvimLspconfigTimer = vim.loop.new_timer()
190+
_G.nvimLspconfigTimer:start(
191+
timeout,
192+
0,
193+
vim.schedule_wrap(function()
194+
local activeServers = #vim.lsp.get_active_clients()
195+
vim.cmd 'LspStop'
196+
vim.notify(
197+
('[lspconfig]: nvim has lost focus, stop current language servers. Number of servers left: %s'):format(
198+
activeServers
199+
),
200+
vim.log.levels.INFO
201+
)
202+
_G.nvimLspconfigTimer = nil
203+
end)
204+
)
205+
end
206+
end,
207+
})
208+
end

0 commit comments

Comments
 (0)