Skip to content

Commit 021b64e

Browse files
authored
Merge pull request #395 from cameronr/main
Fix: #208 stop LSs when restoring session
2 parents 8d2eddb + 1ba7a78 commit 021b64e

File tree

6 files changed

+109
-30
lines changed

6 files changed

+109
-30
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,14 @@ Here are the default settings:
6666
auto_restore_last_session = false, -- On startup, loads the last saved session if session for cwd does not exist
6767
use_git_branch = false, -- Include git branch name in session name
6868
lazy_support = true, -- Automatically detect if Lazy.nvim is being used and wait until Lazy is done to make sure session is restored correctly. Does nothing if Lazy isn't being used. Can be disabled if a problem is suspected or for debugging
69-
bypass_save_filetypes = nil, -- List of file types to bypass auto save when the only buffer open is one of the file types listed, useful to ignore dashboards
69+
bypass_save_filetypes = nil, -- List of filetypes to bypass auto save when the only buffer open is one of the file types listed, useful to ignore dashboards
7070
close_unsupported_windows = true, -- Close windows that aren't backed by normal file before autosaving a session
7171
args_allow_single_directory = true, -- Follow normal sesion save/load logic if launched with a single directory as the only argument
7272
args_allow_files_auto_save = false, -- Allow saving a session even when launched with a file argument (or multiple files/dirs). It does not load any existing session first. While you can just set this to true, you probably want to set it to a function that decides when to save a session when launched with file args. See documentation for more detail
7373
continue_restore_on_error = true, -- Keep loading the session even if there's an error
7474
show_auto_restore_notif = false, -- Whether to show a notification when auto-restoring
7575
cwd_change_handling = false, -- Follow cwd changes, saving a session before change and restoring after
76+
lsp_stop_on_restore = false, -- Should language servers be stopped when restoring a session. Can also be a function that will be called if set. Not called on autorestore from startup
7677
log_level = "error", -- Sets the log level of the plugin (debug, info, warn, error).
7778

7879
session_lens = {

doc/auto-session.txt

+21-12
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ AutoSession.Config *AutoSession.Config*
3030
{show_auto_restore_notif?} (boolean) Whether to show a notification when auto-restoring
3131
{log_level?} (string|integer) "debug", "info", "warn", "error" or vim.log.levels.DEBUG, vim.log.levels.INFO, vim.log.levels.WARN, vim.log.levels.ERROR
3232
{cwd_change_handling?} (boolean) Follow cwd changes, saving a session before change and restoring after
33+
{lsp_stop_on_restore?} (boolean|function) Should language servers be stopped when restoring a session. Can also be a function that will be called if set. Not called on autorestore from startup
3334
{session_lens?} (SessionLens) Session lens configuration options
3435
{pre_save_cmds?} (table) executes before a session is saved
3536

@@ -124,11 +125,12 @@ AutoSession.AutoSaveSession() *AutoSession.AutoSaveSession*
124125

125126

126127
*AutoSession.AutoRestoreSession*
127-
AutoSession.AutoRestoreSession({session_name?})
128+
AutoSession.AutoRestoreSession({session_name?}, {is_startup?})
128129
Function called by AutoSession when automatically restoring a session.
129130

130131
Parameters: ~
131-
{session_name?} (string) An optional session to load
132+
{session_name?} (string) An optional session to load
133+
{is_startup?} (boolean|nil) Is this autorestore happening on startup
132134

133135
Returns: ~
134136
(boolean) returns whether restoring the session was successful or not.
@@ -161,34 +163,41 @@ AutoSession.SaveSessionToDir({session_dir}, {session_name?}, {show_message?})
161163
(boolean)
162164

163165

166+
RestoreOpts *RestoreOpts*
167+
168+
Fields: ~
169+
{show_message} (boolean|nil) Should messages be shown
170+
{is_startup_autorestore} (boolean|nil) True if this is the the startup autorestore
171+
172+
164173
*AutoSession.RestoreSession*
165-
AutoSession.RestoreSession({session_name?}, {show_message?})
174+
AutoSession.RestoreSession({session_name?}, {opts?})
166175
Restores a session from the passed in directory. If no optional session name
167176
is passed in, it uses the cwd as the session name
168177

169178
Parameters: ~
170-
{session_name?} (string|nil) Optional session name
171-
{show_message?} (boolean) Optional, whether to show a message on restore (true by default)
179+
{session_name?} (string|nil) Optional session name
180+
{opts?} (RestoreOpts|nil) restore options
172181

173182

174183
*AutoSession.RestoreSessionFromDir*
175-
AutoSession.RestoreSessionFromDir({session_dir}, {session_name?}, {show_message?})
184+
AutoSession.RestoreSessionFromDir({session_dir}, {session_name?}, {opts?})
176185
Restores a session from the passed in directory. If no optional session name
177186
is passed in, it uses the cwd as the session name
178187

179188
Parameters: ~
180-
{session_dir} (string) Directory to write the session file to
181-
{session_name?} (string|nil) Optional session name
182-
{show_message?} (boolean) Optional, whether to show a message on restore (true by default)
189+
{session_dir} (string) Directory to write the session file to
190+
{session_name?} (string|nil) Optional session name
191+
{opts?} (RestoreOpts|nil) restore options
183192

184193

185194
*AutoSession.RestoreSessionFile*
186-
AutoSession.RestoreSessionFile({session_path}, {show_message?})
195+
AutoSession.RestoreSessionFile({session_path}, {opts?})
187196
Restores a session from a specific file
188197

189198
Parameters: ~
190-
{session_path} (string) The session file to load
191-
{show_message?} (boolean) Optional, whether to show a message on restore (true by default)
199+
{session_path} (string) The session file to load
200+
{opts?} (RestoreOpts|nil) restore options
192201

193202
Returns: ~
194203
(boolean) a session restored

lua/auto-session/config.lua

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ local M = {}
2626
---@field show_auto_restore_notif? boolean Whether to show a notification when auto-restoring
2727
---@field log_level? string|integer "debug", "info", "warn", "error" or vim.log.levels.DEBUG, vim.log.levels.INFO, vim.log.levels.WARN, vim.log.levels.ERROR
2828
---@field cwd_change_handling? boolean Follow cwd changes, saving a session before change and restoring after
29+
---@field lsp_stop_on_restore? boolean|function Should language servers be stopped when restoring a session. Can also be a function that will be called if set. Not called on autorestore from startup
2930
---@field session_lens? SessionLens Session lens configuration options
3031
---
3132
---Hooks
@@ -79,6 +80,7 @@ local defaults = {
7980
continue_restore_on_error = true, -- Keep loading the session even if there's an error
8081
show_auto_restore_notif = false, -- Whether to show a notification when auto-restoring
8182
cwd_change_handling = false, -- Follow cwd changes, saving a session before change and restoring after
83+
lsp_stop_on_restore = false, -- Should language servers be stopped when restoring a session. Can also be a function that will be called if set. Not called on autorestore from startup
8284
log_level = "error", -- Sets the log level of the plugin (debug, info, warn, error).
8385

8486
---@type SessionLens

lua/auto-session/init.lua

+48-17
Original file line numberDiff line numberDiff line change
@@ -438,14 +438,19 @@ end
438438

439439
---Function called by AutoSession when automatically restoring a session.
440440
---@param session_name? string An optional session to load
441+
---@param is_startup? boolean|nil Is this autorestore happening on startup
441442
---@return boolean boolean returns whether restoring the session was successful or not.
442-
function AutoSession.AutoRestoreSession(session_name)
443+
function AutoSession.AutoRestoreSession(session_name, is_startup)
443444
-- WARN: should this be checking is_allowed_dir as well?
444445
if not is_enabled() or not auto_restore() or suppress_session(session_name) then
445446
return false
446447
end
447448

448-
return AutoSession.RestoreSession(session_name, Config.show_auto_restore_notif)
449+
local opts = {
450+
show_message = Config.show_auto_restore_notif,
451+
is_startup_autorestore = is_startup,
452+
}
453+
return AutoSession.RestoreSession(session_name, opts)
449454
end
450455

451456
---@private
@@ -471,7 +476,7 @@ function AutoSession.auto_restore_session_at_vim_enter()
471476
local session_name = Lib.remove_trailing_separator(vim.fn.fnamemodify(launch_argv[1], ":p"))
472477
Lib.logger.debug("Launched with single directory, using as session_dir: " .. session_name)
473478

474-
if AutoSession.AutoRestoreSession(session_name) then
479+
if AutoSession.AutoRestoreSession(session_name, true) then
475480
return true
476481
end
477482

@@ -482,7 +487,7 @@ function AutoSession.auto_restore_session_at_vim_enter()
482487
Config.auto_save = false
483488
end
484489
else
485-
if AutoSession.AutoRestoreSession() then
490+
if AutoSession.AutoRestoreSession(nil, true) then
486491
return true
487492
end
488493

@@ -493,7 +498,12 @@ function AutoSession.auto_restore_session_at_vim_enter()
493498
local last_session_name = Lib.get_latest_session(AutoSession.get_root_dir())
494499
if last_session_name then
495500
Lib.logger.debug("Found last session: " .. last_session_name)
496-
if AutoSession.RestoreSession(last_session_name, Config.show_auto_restore_notif) then
501+
if
502+
AutoSession.RestoreSession(
503+
last_session_name,
504+
{ show_message = Config.show_auto_restore_notif, is_startup_autorestore = true }
505+
)
506+
then
497507
return true
498508
end
499509
end
@@ -576,21 +586,26 @@ function AutoSession.SaveSessionToDir(session_dir, session_name, show_message)
576586
return true
577587
end
578588

589+
---@class RestoreOpts
590+
---@field show_message boolean|nil Should messages be shown
591+
---@field is_startup_autorestore boolean|nil True if this is the the startup autorestore
592+
579593
---Restores a session from the passed in directory. If no optional session name
580594
---is passed in, it uses the cwd as the session name
581595
---@param session_name? string|nil Optional session name
582-
---@param show_message? boolean Optional, whether to show a message on restore (true by default)
583-
function AutoSession.RestoreSession(session_name, show_message)
584-
return AutoSession.RestoreSessionFromDir(AutoSession.get_root_dir(), session_name, show_message)
596+
---@param opts? RestoreOpts|nil restore options
597+
function AutoSession.RestoreSession(session_name, opts)
598+
return AutoSession.RestoreSessionFromDir(AutoSession.get_root_dir(), session_name, opts)
585599
end
586600

587601
---Restores a session from the passed in directory. If no optional session name
588602
---is passed in, it uses the cwd as the session name
589603
---@param session_dir string Directory to write the session file to
590604
---@param session_name? string|nil Optional session name
591-
---@param show_message? boolean Optional, whether to show a message on restore (true by default)
592-
function AutoSession.RestoreSessionFromDir(session_dir, session_name, show_message)
605+
---@param opts? RestoreOpts|nil restore options
606+
function AutoSession.RestoreSessionFromDir(session_dir, session_name, opts)
593607
Lib.logger.debug("RestoreSessionFromDir start", { session_dir, session_name })
608+
opts = opts or {}
594609
-- Canonicalize and create session_dir if needed
595610
session_dir = Lib.validate_root_dir(session_dir)
596611
Lib.logger.debug("RestoreSessionFromDir validated session_dir: ", session_dir)
@@ -623,7 +638,7 @@ function AutoSession.RestoreSessionFromDir(session_dir, session_name, show_messa
623638
local legacy_session_path = session_dir .. legacy_escaped_session_name
624639

625640
if vim.fn.filereadable(legacy_session_path) ~= 1 then
626-
if show_message == nil or show_message then
641+
if opts.show_message == nil or opts.show_message then
627642
vim.notify("Could not restore session: " .. Lib.get_session_display_name(escaped_session_name))
628643
end
629644
return false
@@ -653,18 +668,34 @@ function AutoSession.RestoreSessionFromDir(session_dir, session_name, show_messa
653668
end
654669
end
655670

656-
return AutoSession.RestoreSessionFile(session_path, show_message)
671+
return AutoSession.RestoreSessionFile(session_path, opts)
657672
end
658673

659674
---Restores a session from a specific file
660675
---@param session_path string The session file to load
661-
---@param show_message? boolean Optional, whether to show a message on restore (true by default)
676+
---@param opts? RestoreOpts|nil restore options
662677
---@return boolean Was a session restored
663-
function AutoSession.RestoreSessionFile(session_path, show_message)
664-
AutoSession.run_cmds "pre_restore"
665-
678+
function AutoSession.RestoreSessionFile(session_path, opts)
666679
Lib.logger.debug("RestoreSessionFile restoring session from: " .. session_path)
680+
opts = opts or {}
667681

682+
AutoSession.run_cmds "pre_restore"
683+
684+
-- Stop any language servers if config is set but don't do
685+
-- this on startup as it causes a perceptible delay (and we
686+
-- know there aren't any language servers anyway)
687+
if not opts.is_startup_autorestore then
688+
if Config.lsp_stop_on_restore then
689+
if type(Config.lsp_stop_on_restore) == "function" then
690+
Config.lsp_stop_on_restore()
691+
else
692+
local clients = vim.lsp.get_clients()
693+
if #clients > 0 then
694+
vim.lsp.stop_client(clients)
695+
end
696+
end
697+
end
698+
end
668699
-- Vim cmds require escaping any % with a \ but we don't want to do that
669700
-- for direct filesystem operations (like in save_extra_cmds_new) so we
670701
-- that here, as late as possible and only for this operation
@@ -709,7 +740,7 @@ Error: ]] .. result)
709740

710741
local session_name = Lib.escaped_session_name_to_session_name(vim.fn.fnamemodify(session_path, ":t"))
711742
Lib.logger.debug("Restored session: " .. session_name)
712-
if show_message == nil or show_message then
743+
if opts.show_message == nil or opts.show_message then
713744
vim.notify("Restored session: " .. session_name)
714745
end
715746

tests/ls_stop_on_restore_spec.lua

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
local TL = require "tests/test_lib"
2+
3+
describe("lsp_stop_on_restore", function()
4+
local as = require "auto-session"
5+
as.setup {}
6+
TL.clearSessionFilesAndBuffers()
7+
vim.cmd("e " .. TL.test_file)
8+
as.SaveSession()
9+
10+
it("calls user function on restore", function()
11+
local stop_called = false
12+
as.setup {
13+
lsp_stop_on_restore = function()
14+
stop_called = true
15+
end,
16+
}
17+
18+
as.RestoreSession()
19+
20+
assert.True(stop_called)
21+
end)
22+
23+
it("doesn't try to stop ls on initial autorestore", function()
24+
local stop_called = false
25+
as.setup {
26+
lsp_stop_on_restore = function()
27+
stop_called = true
28+
end,
29+
}
30+
31+
as.auto_restore_session_at_vim_enter()
32+
33+
assert.False(stop_called)
34+
end)
35+
end)

tests/test_lib.lua

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require "plenary"
12
local asLib = require "auto-session.lib"
23
local M = {}
34

0 commit comments

Comments
 (0)