diff --git a/README.md b/README.md index 32958dd..d5aa18a 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ require("persisted").setup({ save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- directory where session files are saved silent = false, -- silent nvim message when sourcing session file use_git_branch = false, -- create session files based on the branch of a git enabled repository + default_branch = "main", -- the branch to load if a session file is not found for the current branch autosave = true, -- automatically save session files when exiting Neovim should_autosave = nil, -- function to determine if a session should be autosaved autoload = false, -- automatically load the session for the cwd on Neovim startup @@ -186,9 +187,7 @@ require("persisted").setup({ }) ``` -> **Note**: If git branching is enabled on a non git enabled repo, then `main` will be used as the default branch - -If you switch branches in a repository, the plugin will try to load a session which corresponds to that branch. If it can't find one, then it will load the session from the `main` branch. +> **Note**: If you initiate git in a repository which has an existing session file, you'll need to add it's branch name to the session name. To do this from within Neovim, use the `:Sessions` command, navigate to the session and press ``. ### Autosaving diff --git a/doc/persisted.nvim.txt b/doc/persisted.nvim.txt index 96dc80f..3edee06 100644 --- a/doc/persisted.nvim.txt +++ b/doc/persisted.nvim.txt @@ -120,14 +120,14 @@ The plugin comes with a number of commands: TELESCOPE EXTENSION ~ -The Telescope extension may be opened via `:Telescope persisted`. +The Telescope extension may be opened via `:Telescope persisted`. The available +actions are: -Once opened, the available keymaps are: - -- `` - Source the session file +- `` - Open/source the session file +- `` - Add/update the git branch for the session file +- `` - Copy the session file - `` - Delete the session file -- `` - Add/update a git branch to the session file GLOBAL VARIABLES ~ @@ -161,7 +161,7 @@ The plugin comes with the following defaults: allowed_dirs = nil, -- table of dirs that the plugin will auto-save and auto-load from ignored_dirs = nil, -- table of dirs that are ignored when auto-saving and auto-loading telescope = { - reset_prompt = true, -- Reset prompt after a telescope action? + reset_prompt = true, -- Reset the Telescope prompt after an action? }, }) < diff --git a/lua/persisted/config.lua b/lua/persisted/config.lua index 6014c25..e5b2984 100644 --- a/lua/persisted/config.lua +++ b/lua/persisted/config.lua @@ -3,8 +3,11 @@ local M = {} local defaults = { save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- directory where session files are saved silent = false, -- silent nvim message when sourcing session file - use_git_branch = false, -- create session files based on the branch of the git enabled repository + + use_git_branch = false, -- create session files based on the branch of a git enabled repository branch_separator = "@@", -- string used to separate session directory name from branch name + default_branch = "main", -- the branch to load if a session file is not found for the current branch + autosave = true, -- automatically save session files when exiting Neovim should_autosave = nil, -- function to determine if a session should be autosaved (resolve to a boolean) @@ -17,6 +20,7 @@ local defaults = { telescope = { reset_prompt = true, -- Reset prompt after a telescope action? + --TODO: We should add a deprecation notice for the old API here }, } diff --git a/lua/persisted/init.lua b/lua/persisted/init.lua index 6e61cd6..de46d6d 100644 --- a/lua/persisted/init.lua +++ b/lua/persisted/init.lua @@ -4,7 +4,19 @@ local config = require("persisted.config") local M = {} local e = vim.fn.fnameescape -local default_branch = "main" + +---Escapes special characters before performing string substitution +---@param str string +---@param pattern string +---@param replace string +---@param n? integer +---@return string +---@return integer count +local function escape_pattern(str, pattern, replace, n) + pattern = string.gsub(pattern, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1") -- escape pattern + replace = string.gsub(replace, "[%%]", "%%%%") -- escape replacement + return string.gsub(str, pattern, replace, n) +end ---Does the current working directory allow for the auto-saving and loading? ---@return boolean @@ -14,6 +26,7 @@ local function allow_dir() if allowed_dirs == nil then return true end + return utils.dirs_match(vim.fn.getcwd(), allowed_dirs) end @@ -33,6 +46,7 @@ end ---@return string local function get_last() local sessions = vim.fn.glob(config.options.save_dir .. "*.vim", true, true) + table.sort(sessions, function(a, b) return vim.loop.fs_stat(a).mtime.sec > vim.loop.fs_stat(b).mtime.sec end) @@ -41,40 +55,57 @@ local function get_last() end ---Get the current Git branch ----@return string +---@return string|nil function M.get_branch() if config.options.use_git_branch then vim.fn.system([[git rev-parse 2> /dev/null]]) + local git_enabled = (vim.v.shell_error == 0) if git_enabled then - local branch = vim.fn.systemlist([[git rev-parse --abbrev-ref HEAD 2>/dev/null]]) + local git_branch = vim.fn.systemlist([[git rev-parse --abbrev-ref HEAD 2>/dev/null]]) + if vim.v.shell_error == 0 then - branch = config.options.branch_separator .. branch[1]:gsub("/", "%%") + local branch = config.options.branch_separator .. git_branch[1]:gsub("/", "%%") local branch_session = config.options.save_dir .. vim.fn.getcwd():gsub(utils.get_dir_pattern(), "%%") .. branch .. ".vim" - -- Try to load the session for the current branch and if not, use the value of default_branch + -- Try to load the session for the current branch if vim.fn.filereadable(branch_session) ~= 0 then return branch else + vim.api.nvim_echo({ + { "[Persisted.nvim]\n", "Question" }, + { "Could not load a session for branch " }, + { git_branch[1] .. "\n", "WarningMsg" }, + { "Trying to load a session for branch " }, + { config.options.default_branch, "Title" }, + { " ..." }, + }, true, {}) + vim.g.persisted_branch_session = branch_session - return config.options.branch_separator .. default_branch + return config.options.branch_separator .. config.options.default_branch end end end - end - return config.options.branch_separator .. default_branch + -- -- INFO: This allows users who have `@@main` in their session name to load + -- -- repositories that are not git enabled + -- if config.options.use_old_branching then + -- return config.options.branch_separator .. config.options.default_branch + -- end + end end ---Get the current session for the current working directory and git branch ---@return string local function get_current() local name = vim.fn.getcwd():gsub(utils.get_dir_pattern(), "%%") - return config.options.save_dir .. name .. M.get_branch() .. ".vim" + local branch = M.get_branch() + + return config.options.save_dir .. name .. (branch or "") .. ".vim" end ---Determine if a session for the current wording directory, exists @@ -105,8 +136,10 @@ function M.load(opt) opt = opt or {} local session = opt.session or (opt.last and get_last() or get_current()) + local session_exists = vim.fn.filereadable(session) ~= 0 + if session then - if vim.fn.filereadable(session) ~= 0 then + if session_exists then vim.g.persisting_session = config.options.follow_cwd and nil or session utils.load_session(session, config.options.silent) elseif type(config.options.on_autoload_no_session) == "function" then @@ -114,6 +147,17 @@ function M.load(opt) end end + if session and not session_exists then + vim.api.nvim_echo({ + { "[Persisted.nvim]\n", "Question" }, + { "Could not find a session for " }, + { vim.fn.getcwd() .. "\n", "WarningMsg" }, + { "As per " }, + { "https://github.com/olimorris/persisted.nvim/discussions/103", "WarningMsg" }, + { " you may need to remove the branch from the name" }, + }, true, {}) + end + if config.options.autosave and (allow_dir() and not ignore_dir()) then M.start() end @@ -212,19 +256,6 @@ function M.toggle() return M.start() end ----Escapes special characters before performing string substitution ----@param str string ----@param pattern string ----@param replace string ----@param n? integer ----@return string ----@return integer count -local function escape_pattern(str, pattern, replace, n) - pattern = string.gsub(pattern, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1") -- escape pattern - replace = string.gsub(replace, "[%%]", "%%%%") -- escape replacement - return string.gsub(str, pattern, replace, n) -end - ---List all of the sessions ---@return table function M.list() @@ -265,6 +296,7 @@ function M.list() ["dir_path"] = dir_path, }) end + return sessions end