refactor: update logic for autoload or starting sessions (#104)
* Update logic for autoload or starting sessions. The logic to prevent autoloading/starting sessions when any arguments are supplied to neovim is to prevent session management from kicking in when editing a single file. This updates the logic to allow a single argument passed to neovim as long as the argument is an existing directory. When neovim is launched in this way it behaves the same as opening neovim with no arguments but has changed the working directory. This results in consistent behavior of the autoloading/starting of sessions when passing a directory argument to start neovim. See: https://github.com/olimorris/persisted.nvim/discussions/93 * Fix comment, make comparisons more direct * Update functions to be directory-aware The main functionality in `init.lua` assumes using current working directory in most cases. This refactors these functions to allow passing in a directory instead. The default behavior is to now use the current directory unless neovim was started with a single directory argument, using that instead. This also special-cases `.` as `vim.fn.expand()` does not resolve that to the current working directory.main
parent
66d540f949
commit
7944b9afe3
|
|
@ -242,7 +242,7 @@ require("persisted").setup({
|
||||||
|
|
||||||
Autoloading can be further controlled for certain directories by specifying `allowed_dirs` and `ignored_dirs`.
|
Autoloading can be further controlled for certain directories by specifying `allowed_dirs` and `ignored_dirs`.
|
||||||
|
|
||||||
> **Note**: Autoloading will not occur if the plugin is lazy loaded or a user opens Neovim with arguments. For example: `nvim some_file.rb`
|
> **Note**: Autoloading will not occur if the plugin is lazy loaded or a user opens Neovim with arguments other than a single directory argument. For example: `nvim some_file.rb` will not not result in autoloading but `nvim some/existing/path` or `nvim .` will.
|
||||||
|
|
||||||
### Following current working directory
|
### Following current working directory
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ Install the plugin with your preferred package manager:
|
||||||
>vim
|
>vim
|
||||||
" Vim Script
|
" Vim Script
|
||||||
Plug 'olimorris/persisted.nvim'
|
Plug 'olimorris/persisted.nvim'
|
||||||
|
|
||||||
lua << EOF
|
lua << EOF
|
||||||
require("persisted").setup {
|
require("persisted").setup {
|
||||||
-- your configuration comes here
|
-- your configuration comes here
|
||||||
|
|
@ -274,7 +274,9 @@ Autoloading can be further controlled for certain directories by specifying
|
||||||
|
|
||||||
|
|
||||||
**Note**Autoloading will not occur if the plugin is lazy loaded or a user opens
|
**Note**Autoloading will not occur if the plugin is lazy loaded or a user opens
|
||||||
Neovim with arguments. For example: `nvim some_file.rb`
|
Neovim with arguments other than a single directory argument. For example:
|
||||||
|
`nvim some_file.rb` will not result in autoloading but
|
||||||
|
`nvim some/existing/path` or `nvim .` will.
|
||||||
|
|
||||||
FOLLOWING CURRENT WORKING DIRECTORY ~
|
FOLLOWING CURRENT WORKING DIRECTORY ~
|
||||||
|
|
||||||
|
|
@ -378,7 +380,7 @@ autocmd can be created to hook into the `PersistedSavePre` event:
|
||||||
|
|
||||||
>lua
|
>lua
|
||||||
local group = vim.api.nvim_create_augroup("PersistedHooks", {})
|
local group = vim.api.nvim_create_augroup("PersistedHooks", {})
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd({ "User" }, {
|
vim.api.nvim_create_autocmd({ "User" }, {
|
||||||
pattern = "PersistedSavePre",
|
pattern = "PersistedSavePre",
|
||||||
group = group,
|
group = group,
|
||||||
|
|
@ -395,14 +397,14 @@ made available to the callbacks:
|
||||||
|
|
||||||
>lua
|
>lua
|
||||||
local group = vim.api.nvim_create_augroup("PersistedHooks", {})
|
local group = vim.api.nvim_create_augroup("PersistedHooks", {})
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd({ "User" }, {
|
vim.api.nvim_create_autocmd({ "User" }, {
|
||||||
pattern = "PersistedTelescopeLoadPre",
|
pattern = "PersistedTelescopeLoadPre",
|
||||||
group = group,
|
group = group,
|
||||||
callback = function(session)
|
callback = function(session)
|
||||||
-- Save the currently loaded session
|
-- Save the currently loaded session
|
||||||
require("persisted").save({ session = vim.g.persisted_loaded_session })
|
require("persisted").save({ session = vim.g.persisted_loaded_session })
|
||||||
|
|
||||||
-- Delete all of the open buffers
|
-- Delete all of the open buffers
|
||||||
vim.api.nvim_input("<ESC>:%bd!<CR>")
|
vim.api.nvim_input("<ESC>:%bd!<CR>")
|
||||||
end,
|
end,
|
||||||
|
|
|
||||||
|
|
@ -18,33 +18,61 @@ local function escape_pattern(str, pattern, replace, n)
|
||||||
return string.gsub(str, pattern, replace, n)
|
return string.gsub(str, pattern, replace, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Does the current working directory allow for the auto-saving and loading?
|
---Checks if vim was started with either zero arguments or a single argument
|
||||||
|
---which is a drectory.
|
||||||
---@return boolean
|
---@return boolean
|
||||||
local function allow_dir()
|
local function is_neovim_start_ok()
|
||||||
|
if vim.fn.argc() == 1 then
|
||||||
|
return vim.fn.isdirectory(vim.fn.argv(0)) ~= 0
|
||||||
|
end
|
||||||
|
return vim.fn.argc() == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
---Gets the directory to be used for sessions.
|
||||||
|
---@return string
|
||||||
|
local function get_start_dir()
|
||||||
|
if vim.fn.argc() == 1 then
|
||||||
|
local dir = vim.fn.expand(vim.fn.argv(0))
|
||||||
|
if dir == '.' then
|
||||||
|
return vim.fn.getcwd()
|
||||||
|
end
|
||||||
|
if vim.fn.isdirectory(dir) ~= 0 then
|
||||||
|
return dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return vim.fn.getcwd()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Does the current working directory allow for the auto-saving and loading?
|
||||||
|
---@param dir string
|
||||||
|
---@return boolean
|
||||||
|
local function allow_dir(dir)
|
||||||
local allowed_dirs = config.options.allowed_dirs
|
local allowed_dirs = config.options.allowed_dirs
|
||||||
|
|
||||||
if allowed_dirs == nil then
|
if allowed_dirs == nil then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return utils.dirs_match(vim.fn.getcwd(), allowed_dirs)
|
return utils.dirs_match(dir, allowed_dirs)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Is the current working directory ignored for auto-saving and loading?
|
---Is the current working directory ignored for auto-saving and loading?
|
||||||
|
---@param dir string
|
||||||
---@return boolean
|
---@return boolean
|
||||||
local function ignore_dir()
|
local function ignore_dir(dir)
|
||||||
local ignored_dirs = config.options.ignored_dirs
|
local ignored_dirs = config.options.ignored_dirs
|
||||||
|
|
||||||
if ignored_dirs == nil then
|
if ignored_dirs == nil then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
return utils.dirs_match(vim.fn.getcwd(), ignored_dirs)
|
return utils.dirs_match(dir, ignored_dirs)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get the session that was saved last
|
---Get the session that was saved last
|
||||||
|
---@param dir string The directory whose last session to load.
|
||||||
---@return string
|
---@return string
|
||||||
local function get_last()
|
local function get_last(dir)
|
||||||
local sessions = vim.fn.glob(config.options.save_dir .. "*.vim", true, true)
|
local sessions = vim.fn.glob(config.options.save_dir .. "*.vim", true, true)
|
||||||
|
|
||||||
table.sort(sessions, function(a, b)
|
table.sort(sessions, function(a, b)
|
||||||
|
|
@ -55,20 +83,22 @@ local function get_last()
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get the current Git branch
|
---Get the current Git branch
|
||||||
|
---@param dir? string The directory to inspect for a Git branch. If not set then the current working directory is used.
|
||||||
---@return string|nil
|
---@return string|nil
|
||||||
function M.get_branch()
|
function M.get_branch(dir)
|
||||||
|
dir = dir or get_start_dir()
|
||||||
if config.options.use_git_branch then
|
if config.options.use_git_branch then
|
||||||
vim.fn.system([[git rev-parse 2> /dev/null]])
|
vim.fn.system("git -C " .. dir .. " rev-parse 2>/dev/null")
|
||||||
|
|
||||||
local git_enabled = (vim.v.shell_error == 0)
|
local git_enabled = (vim.v.shell_error == 0)
|
||||||
|
|
||||||
if git_enabled then
|
if git_enabled then
|
||||||
local git_branch = vim.fn.systemlist([[git rev-parse --abbrev-ref HEAD 2>/dev/null]])
|
local git_branch = vim.fn.systemlist("git -C " .. dir .. " rev-parse --abbrev-ref HEAD 2>/dev/null")
|
||||||
|
|
||||||
if vim.v.shell_error == 0 then
|
if vim.v.shell_error == 0 then
|
||||||
local branch = config.options.branch_separator .. git_branch[1]:gsub("/", "%%")
|
local branch = config.options.branch_separator .. git_branch[1]:gsub("/", "%%")
|
||||||
local branch_session = config.options.save_dir
|
local branch_session = config.options.save_dir
|
||||||
.. vim.fn.getcwd():gsub(utils.get_dir_pattern(), "%%")
|
.. dir:gsub(utils.get_dir_pattern(), "%%")
|
||||||
.. branch
|
.. branch
|
||||||
.. ".vim"
|
.. ".vim"
|
||||||
|
|
||||||
|
|
@ -100,18 +130,21 @@ function M.get_branch()
|
||||||
end
|
end
|
||||||
|
|
||||||
---Get the current session for the current working directory and git branch
|
---Get the current session for the current working directory and git branch
|
||||||
|
---@param dir string The directory whose session file to get.
|
||||||
---@return string
|
---@return string
|
||||||
local function get_current()
|
local function get_current(dir)
|
||||||
local name = vim.fn.getcwd():gsub(utils.get_dir_pattern(), "%%")
|
local name = dir:gsub(utils.get_dir_pattern(), "%%")
|
||||||
local branch = M.get_branch()
|
local branch = M.get_branch(dir)
|
||||||
|
|
||||||
return config.options.save_dir .. name .. (branch or "") .. ".vim"
|
return config.options.save_dir .. name .. (branch or "") .. ".vim"
|
||||||
end
|
end
|
||||||
|
|
||||||
---Determine if a session for the current wording directory, exists
|
---Determine if a session for the current wording directory, exists
|
||||||
|
---@param dir? string The directory whose associated session to check if exists. If not set, current working directory is used.
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function M.session_exists()
|
function M.session_exists(dir)
|
||||||
return vim.fn.filereadable(get_current()) ~= 0
|
dir = dir or get_start_dir()
|
||||||
|
return vim.fn.filereadable(get_current(dir)) ~= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
---Setup the plugin
|
---Setup the plugin
|
||||||
|
|
@ -120,10 +153,11 @@ end
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
config.setup(opts)
|
config.setup(opts)
|
||||||
|
|
||||||
|
local dir = get_start_dir()
|
||||||
if
|
if
|
||||||
config.options.autosave
|
config.options.autosave
|
||||||
and (allow_dir() and not ignore_dir() and vim.g.persisting == nil)
|
and (allow_dir(dir) and not ignore_dir(dir) and vim.g.persisting == nil)
|
||||||
and vim.fn.argc() == 0
|
and is_neovim_start_ok()
|
||||||
then
|
then
|
||||||
M.start()
|
M.start()
|
||||||
end
|
end
|
||||||
|
|
@ -131,10 +165,12 @@ end
|
||||||
|
|
||||||
---Load a session
|
---Load a session
|
||||||
---@param opt? table
|
---@param opt? table
|
||||||
|
---@param dir? string
|
||||||
---@return nil
|
---@return nil
|
||||||
function M.load(opt)
|
function M.load(opt, dir)
|
||||||
opt = opt or {}
|
opt = opt or {}
|
||||||
local session = opt.session or (opt.last and get_last() or get_current())
|
dir = dir or get_start_dir()
|
||||||
|
local session = opt.session or (opt.last and get_last(dir) or get_current(dir))
|
||||||
|
|
||||||
local session_exists = vim.fn.filereadable(session) ~= 0
|
local session_exists = vim.fn.filereadable(session) ~= 0
|
||||||
|
|
||||||
|
|
@ -158,7 +194,7 @@ function M.load(opt)
|
||||||
}, true, {})
|
}, true, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.options.autosave and (allow_dir() and not ignore_dir()) then
|
if config.options.autosave and (allow_dir(dir) and not ignore_dir(dir)) then
|
||||||
M.start()
|
M.start()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -166,10 +202,10 @@ end
|
||||||
---Automatically load the session for the current dir
|
---Automatically load the session for the current dir
|
||||||
---@return nil
|
---@return nil
|
||||||
function M.autoload()
|
function M.autoload()
|
||||||
-- Ensure that no arguments have been passed to Neovim
|
local dir = get_start_dir()
|
||||||
if config.options.autoload and vim.fn.argc() == 0 then
|
if config.options.autoload and is_neovim_start_ok() then
|
||||||
if allow_dir() and not ignore_dir() then
|
if allow_dir(dir) and not ignore_dir(dir) then
|
||||||
M.load()
|
M.load({}, dir)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -201,9 +237,11 @@ end
|
||||||
|
|
||||||
---Save the session
|
---Save the session
|
||||||
---@param opt? table
|
---@param opt? table
|
||||||
|
---@param dir? string
|
||||||
---@return nil
|
---@return nil
|
||||||
function M.save(opt)
|
function M.save(opt, dir)
|
||||||
opt = opt or {}
|
opt = opt or {}
|
||||||
|
dir = dir or get_start_dir()
|
||||||
|
|
||||||
if not opt.session then
|
if not opt.session then
|
||||||
-- Do not save the session if the user has manually stopped it...unless it's forced
|
-- Do not save the session if the user has manually stopped it...unless it's forced
|
||||||
|
|
@ -222,14 +260,16 @@ function M.save(opt)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local session = opt.session or (vim.g.persisted_branch_session or vim.g.persisting_session or get_current())
|
local session = opt.session or (vim.g.persisted_branch_session or vim.g.persisting_session or get_current(dir))
|
||||||
write(session)
|
write(session)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Delete the current session
|
---Delete the current session
|
||||||
|
---@param dir? string The directory whose associated session to delete. If not set, the current working directory is used.
|
||||||
---@return nil
|
---@return nil
|
||||||
function M.delete()
|
function M.delete(dir)
|
||||||
local session = get_current()
|
dir = dir or get_start_dir()
|
||||||
|
local session = get_current(dir)
|
||||||
if session and vim.loop.fs_stat(session) ~= 0 then
|
if session and vim.loop.fs_stat(session) ~= 0 then
|
||||||
vim.api.nvim_exec_autocmds("User", { pattern = "PersistedDeletePre", data = { name = session } })
|
vim.api.nvim_exec_autocmds("User", { pattern = "PersistedDeletePre", data = { name = session } })
|
||||||
|
|
||||||
|
|
@ -243,12 +283,14 @@ function M.delete()
|
||||||
end
|
end
|
||||||
|
|
||||||
---Determines whether to load, start or stop a session
|
---Determines whether to load, start or stop a session
|
||||||
|
---@param dir? string The directory whose associated session saving should be toggled. If not set, the current working directory is used.
|
||||||
---@return nil
|
---@return nil
|
||||||
function M.toggle()
|
function M.toggle(dir)
|
||||||
vim.api.nvim_exec_autocmds("User", { pattern = "PersistedToggled" })
|
vim.api.nvim_exec_autocmds("User", { pattern = "PersistedToggled" })
|
||||||
|
dir = dir or get_start_dir()
|
||||||
|
|
||||||
if vim.g.persisting == nil then
|
if vim.g.persisting == nil then
|
||||||
return M.load()
|
return M.load({}, dir)
|
||||||
end
|
end
|
||||||
if vim.g.persisting then
|
if vim.g.persisting then
|
||||||
return M.stop()
|
return M.stop()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue