Skip to content

Commit

Permalink
Merge pull request #315 from cameronr/unify-search
Browse files Browse the repository at this point in the history
Unify session selection logic, Fixes #287
  • Loading branch information
rmagatti authored Jul 7, 2024
2 parents 4685eaf + 63b8194 commit d5f5c18
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 33 deletions.
15 changes: 14 additions & 1 deletion lua/auto-session/autocmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local M = {}
---@param config table auto session config
---@param AutoSession table auto session instance
M.setup_autocmds = function(config, AutoSession)
if not config.cwd_change_handling or vim.tbl_isempty(config.cwd_change_handling or {}) then
if not config.cwd_change_handling or not config.cwd_change_handling.restore_upcoming_session then
Lib.logger.debug "cwd_change_handling is disabled, skipping setting DirChangedPre and DirChanged autocmd handling"
return
end
Expand All @@ -30,10 +30,18 @@ M.setup_autocmds = function(config, AutoSession)
return
end

if AutoSession.restore_in_progress then
Lib.logger.debug "DirChangedPre: restore_in_progress is true, ignoring this event"
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.
vim.cmd "%bd!"

vim.cmd "clearjumps"

if type(conf.pre_cwd_changed_hook) == "function" then
Expand All @@ -56,6 +64,11 @@ M.setup_autocmds = function(config, AutoSession)
return
end

if AutoSession.restore_in_progress then
Lib.logger.debug "DirChanged: restore_in_progress is true, ignoring this event"
return
end

-- all buffers should've been deleted in `DirChangedPre`, something probably went wrong
if Lib.has_open_buffers() then
Lib.logger.debug "Cancelling session restore"
Expand Down
60 changes: 54 additions & 6 deletions lua/auto-session/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ end
-- get the current git branch name, if any, and only if configured to do so
local function get_branch_name()
if AutoSession.conf.auto_session_use_git_branch then
-- WARN: this assumes you want the branch of the cwd
local out = vim.fn.systemlist "git rev-parse --abbrev-ref HEAD"
if vim.v.shell_error ~= 0 then
Lib.logger.debug(string.format("git failed with: %s", table.concat(out, "\n")))
Expand Down Expand Up @@ -479,11 +480,14 @@ function AutoSession.get_session_files()
end

local entries = vim.fn.readdir(sessions_dir, function(item)
return vim.fn.isdirectory(item) == 0 and not string.find(item, "x.vim$")
return Lib.is_session_file(sessions_dir, item)
end)

-- Get cross platform path separator
local path_separator = Lib.get_path_separator()

return vim.tbl_map(function(entry)
return { display_name = AutoSession.format_file_name(entry), path = entry }
return { display_name = AutoSession.format_file_name(entry), path = sessions_dir .. path_separator .. entry }
end, entries)
end

Expand All @@ -509,10 +513,7 @@ local function handle_autosession_command(data)
local files = AutoSession.get_session_files()
if data.args:match "search" then
open_picker(files, "Select a session:", function(choice)
-- Change dir to selected session path, the DirChangePre and DirChange events will take care of the rest
-- BUG: The above is only true if cwd_change_handling is true which means sessions
-- won't be restored if cwd_change_handling is false
vim.fn.chdir(choice.display_name)
AutoSession.restore_selected_session(choice.path)
end)
elseif data.args:match "delete" then
open_picker(files, "Delete a session:", function(choice)
Expand All @@ -521,6 +522,52 @@ local function handle_autosession_command(data)
end
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)

AutoSession.AutoSaveSession()

-- NOTE:
-- In theory, this is supposed to keep open buffers that are in buftypes_to_ignore. However, even if
-- we keep them open here, they'll be cleared when we source the session file sp I don't think
-- this code does anything. It also interrupts session loading if the buffer replaced is loaded
-- by another process. So, I've replaced it with %bd! which is what cwd_change_handling does.
-- This code and block should be removed when it's confirmed that no users are using it effectively
--
-- local buffers = vim.api.nvim_list_bufs()
-- for _, bufn in pairs(buffers) do
-- if
-- not vim.tbl_contains(
-- AutoSession.conf.session_lens.buftypes_to_ignore,
-- vim.api.nvim_get_option_value("buftype", { buf = bufn })
-- )
-- then
-- vim.cmd("silent bwipeout!" .. bufn)
-- else
-- Lib.logger.debug "[restore_selected_session] Not closing buffer because it matches buftypes_to_ignore"
-- end
-- end

vim.cmd "%bd!"

-- 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

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

vim.api.nvim_create_user_command("Autosession", handle_autosession_command, { nargs = 1 })

-- local function write_to_session_control(session_file_name)
Expand Down Expand Up @@ -767,6 +814,7 @@ Disabling auto save. Please check for errors in your config. Error:
elseif session_file then
Lib.logger.debug "Using session FILE"
local escaped_file = session_file:gsub("%%", "\\%%")
Lib.logger.debug("Using session FILE: " .. escaped_file)
if Lib.is_readable(escaped_file) then
Lib.logger.debug "isReadable, calling restore"
RESTORED_WITH = restore(escaped_file)
Expand Down
33 changes: 33 additions & 0 deletions lua/auto-session/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,37 @@ function Lib.close_unsupported_windows()
end
end

function Lib.get_path_separator()
-- Get cross platform path separator
return package.config:sub(1, 1)
end

-- When Neovim makes a session file, it may save an additional <filename>x.vim file
-- with custom user commands. This function returns false if it's one of those files
function Lib.is_session_file(session_dir, file_path)
-- if it's a directory, don't include
if vim.fn.isdirectory(file_path) ~= 0 then
return false
end

-- if it's a file that doesn't end in x.vim, include
if not string.find(file_path, "x.vim$") then
return true
end

local path_separator = Lib.get_path_separator()

-- the file ends in x.vim, make sure it has SessionLoad on the first line
local file = io.open(session_dir .. path_separator .. file_path, "r")
if not file then
Lib.logger.debug("Could not open file: " .. session_dir .. path_separator .. file_path)
return false
end

local first_line = file:read "*line"
file:close()

return first_line and string.find(first_line, "SessionLoad") ~= nil
end

return Lib
26 changes: 1 addition & 25 deletions lua/auto-session/session-lens/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,7 @@ local function source_session(selection, prompt_bufnr)
end

vim.defer_fn(function()
local cwd_change_handling_conf = M.functions.conf.cwd_change_handling

-- If cwd_change_handling is true, the current session will be saved in the DirChangedPre AutoCmd
-- and the new session will be restored in DirChanged
if type(cwd_change_handling_conf) == "table" and cwd_change_handling_conf.restore_upcoming_session then
-- Take advatage of cwd_change_handling behaviour for switching sessions
Lib.logger.debug "Triggering vim.fn.chdir since cwd_change_handling feature is enabled"
vim.fn.chdir(M.functions.format_file_name(type(selection) == "table" and selection.filename or selection))
else
-- TODO: Since cwd_change_handling is disabled, we save and restore here. This would probably be better
-- handled in AutoSession itself since the same case comes up if the built in picker is used
-- (e.g. :Autosession search).
Lib.logger.debug "Triggering session-lens behaviour since cwd_change_handling feature is disabled"
M.functions.AutoSaveSession()

local buffers = vim.api.nvim_list_bufs()
for _, bufn in pairs(buffers) do
if not vim.tbl_contains(M.conf.buftypes_to_ignore, vim.api.nvim_buf_get_option(bufn, "buftype")) then
vim.cmd("silent bwipeout!" .. bufn)
end
end

vim.cmd "clearjumps"
M.functions.RestoreSession(type(selection) == "table" and selection.path or selection)
end
M.functions.restore_selected_session(type(selection) == "table" and selection.path)
end, 50)
end

Expand Down
6 changes: 5 additions & 1 deletion lua/auto-session/session-lens/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ local SessionLens = {
---@field shorten_path boolean Deprecated, pass { 'shorten' } to path_display
---@field path_display table An array that specifies how to handle paths. Read :h telescope.defaults.path_display
---@field theme_conf table
---@field buftypes_to_ignore table
---@field buftypes_to_ignore table Deprecated, if you're using this please report your usage on github
---@field previewer boolean
---@field session_control session_control
---@field load_on_setup boolean
Expand All @@ -37,6 +37,10 @@ function SessionLens.setup(auto_session)
Lib.setup(SessionLens.conf, auto_session)
Actions.setup(SessionLens.conf, auto_session)
logger.log_level = auto_session.conf.log_level

if SessionLens.conf.buftypes_to_ignore ~= nil and not vim.tbl_isempty(SessionLens.conf.buftypes_to_ignore) then
logger.warn('buftypes_to_ignore is deprecated. If you think you need this option, please file a bug on GitHub. If not, please remove it from your config')
end
end

---Search session
Expand Down
6 changes: 6 additions & 0 deletions lua/auto-session/session-lens/library.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ end
function Lib.make_entry.gen_from_file(opts)
local root = Lib.functions.get_root_dir()
return function(line)
-- Don't include <session>x.vim files that nvim makes for custom user
-- commands
if not AutoSessionLib.is_session_file(root, line) then
return nil
end

return {
ordinal = line,
value = line,
Expand Down

0 comments on commit d5f5c18

Please sign in to comment.