Skip to content

Commit

Permalink
fix: #200 Prevent cd loading a session while already restoring sesssion
Browse files Browse the repository at this point in the history
If `cwd_change_handling = true` and `sessionoptions` contains `curdir`,
the session will contain a cd command to change to the directory where
the session was saved. That would trigger DirChangedPre/DirChanged and
DirChanged would try to load the session again. Obviously, we don't want
to do that. We have previously prevented it for AutoRestoreSession and
loading a session via search but it's better to do it in RestoreSession
to handle all of the cases.
  • Loading branch information
cameronr committed Jul 15, 2024
1 parent 2102c22 commit 7186e61
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
15 changes: 13 additions & 2 deletions lua/auto-session/autocmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,21 @@ M.setup_autocmds = function(config, AutoSession)

if AutoSession.restore_in_progress then
Lib.logger.debug "DirChangedPre: restore_in_progress is true, ignoring this event"
-- NOTE: We don't call the cwd_changed_hook here
-- I think that's probably the right choice because I assume that event is mostly
-- for preparing sessions for save/restoring but we don't want to do that when we're
-- already restoring a session
return
end

AutoSession.AutoSaveSession()

-- Clear all buffers and jumps after session save so session doesn't blead over to next session.
-- NOTE: If the code in restore_selected_session that tries to keep matching buftypes open across
-- sessions actually works, we should also have that logic here.

-- BUG: I think this is probably better done in RestoreSession. If we do it here and the
-- directory change fails (e.g. it doesn't exist), we'll have cleared the buffers and still be
-- in the same directory. If autosaving is enabled, we'll save an empty session when we exit
-- blowing away the session we were trying to save
vim.cmd "%bd!"

vim.cmd "clearjumps"
Expand All @@ -65,6 +72,10 @@ M.setup_autocmds = function(config, AutoSession)
end

if AutoSession.restore_in_progress then
-- NOTE: We don't call the cwd_changed_hook here (or in the other case below)
-- I think that's probably the right choice because I assume that event is mostly
-- for preparing sessions for save/restoring but we don't want to do that when we're
-- already restoring a session
Lib.logger.debug "DirChanged: restore_in_progress is true, ignoring this event"
return
end
Expand Down
27 changes: 12 additions & 15 deletions lua/auto-session/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -613,8 +613,6 @@ local function handle_autosession_command(data)
end

-- Handler for when a session is picked from the UI, either via Telescope or via AutoSession.select_session
-- We'll load the selected session file, setting restore_in_progress so DirChangedPre/DirChanged won't
-- also try to load the session when the directory is changed
function AutoSession.restore_selected_session(session_filename)
Lib.logger.debug("[restore_selected_session]: filename: " .. session_filename)

Expand Down Expand Up @@ -646,16 +644,13 @@ function AutoSession.restore_selected_session(session_filename)
-- Would it be better to always clear jumps in RestoreSession?
vim.cmd "clearjumps"

-- Set restore_in_progress so cwd_change_handling won't also try to load the session when the directory is changed
-- And use a pcall to make sure we unset the flag whether loading was successful or not
AutoSession.restore_in_progress = true
local success, result = pcall(AutoSession.RestoreSession, session_filename)
AutoSession.restore_in_progress = false
local result = AutoSession.RestoreSession(session_filename)

if not success or not result then
if not result then
Lib.logger.info("Could not load session for filename: " .. session_filename)
return
end

return result
end

vim.api.nvim_create_user_command("Autosession", handle_autosession_command, { nargs = 1 })
Expand Down Expand Up @@ -813,12 +808,7 @@ local function auto_restore_session_at_vim_enter()
Lib.logger.debug("Launched with single directory, using as session_dir: " .. session_dir)
end

-- Restoring here may change the cwd so disable cwd processing while restoring
AutoSession.restore_in_progress = true
local success, result = pcall(AutoSession.AutoRestoreSession, session_dir)
AutoSession.restore_in_progress = false

if success and result then
if AutoSession.AutoRestoreSession(session_dir) then
return true
end

Expand Down Expand Up @@ -856,6 +846,8 @@ local function extract_dir_or_file(session_dir_or_file)
end

---RestoreSessionFromFile takes a session_file and calls RestoreSession after parsing the provided parameter.
-- Will set restore_in_progress so DirChangedPre/DirChanged won't also try to
-- load the session when the directory is changed
---@param session_file string
function AutoSession.RestoreSessionFromFile(session_file)
AutoSession.RestoreSession(string.format(AutoSession.get_root_dir() .. "%s.vim", session_file:gsub("/", "%%")))
Expand All @@ -875,7 +867,12 @@ function AutoSession.RestoreSession(sessions_dir_or_file)
run_hook_cmds(pre_cmds, "pre-restore")

local cmd = AutoSession.conf.silent_restore and "silent source " .. file_path or "source " .. file_path

-- Set restore_in_progress here so we won't also try to save/load the session if
-- cwd_change_handling = true and the session contains a cd command
AutoSession.restore_in_progress = true
local success, result = pcall(vim.cmd, cmd)
AutoSession.restore_in_progress = false

-- Clear any saved command line args since we don't need them anymore
launch_argv = nil
Expand Down

0 comments on commit 7186e61

Please sign in to comment.