diff --git a/README.md b/README.md index 21aacaf..1f28e48 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ require("persisted").setup({ follow_cwd = true, -- change session file name to match current working directory if it changes 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 + ignored_branches = nil, -- table of branch patterns that are ignored for auto-saving and auto-loading telescope = { reset_prompt = true, -- Reset the Telescope prompt after an action? mappings = { -- table of mappings for the Telescope extension @@ -322,6 +323,19 @@ require("persisted").setup({ In this setup, `~/.config` and `~/.local/nvim` are still going to behave in their default setting (ignoring all listed directory and its children), however `/` and `/tmp` will only ignore those directories exactly. +### Ignored branches + +You may specify a table of patterns that match against braches for which the plugin will **never** autosave and autoload from. For example: + +```lua +require("persisted").setup({ + ignored_branches = { + "^master", + "feature/%u" + }, +}) +``` + ### Events / Callbacks The plugin fires events at various points during its lifecycle: diff --git a/lua/persisted/config.lua b/lua/persisted/config.lua index a32659e..fccd4d3 100644 --- a/lua/persisted/config.lua +++ b/lua/persisted/config.lua @@ -17,6 +17,7 @@ local defaults = { follow_cwd = true, -- change session file name with changes in current working directory 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 for auto-saving and auto-loading + ignored_branches = nil, -- table of branch patterns that are ignored for auto-saving and auto-loading telescope = { reset_prompt = true, -- Reset prompt after a telescope action? diff --git a/lua/persisted/init.lua b/lua/persisted/init.lua index ac4db48..95c4f1a 100644 --- a/lua/persisted/init.lua +++ b/lua/persisted/init.lua @@ -79,6 +79,19 @@ local function ignore_dir(dir) return utils.dirs_match(dir, ignored_dirs) end +---Is the current branch ignored for auto-saving and loading? +---@param dir string Branch to be used for the session +---@return boolean +local function ignore_branch(branch) + local ignored_branches = config.options.ignored_branches + + if ignored_branches == nil then + return false + end + + return utils.table_match(branch, ignored_branches) ~= nil +end + ---Get the session that was saved last ---@return string local function get_last() @@ -91,6 +104,24 @@ local function get_last() return sessions[1] end + +---Get the current Git branch name, untouched +---@param dir? string Directory to be used for the session +---@return string|nil +local function get_branchname(dir) + dir = dir or session_dir() + vim.fn.system('git -C "' .. dir .. '" rev-parse 2>/dev/null') + + local git_enabled = (vim.v.shell_error == 0) + + if git_enabled then + local git_branch = vim.fn.systemlist('git -C "' .. dir .. '" rev-parse --abbrev-ref HEAD 2>/dev/null') + return git_branch[1] + end + + return nil +end + ---Get the current Git branch ---@param dir? string Directory to be used for the session ---@return string|nil @@ -154,10 +185,12 @@ end function M.setup(opts) config.setup(opts) local dir = session_dir() + local branch = get_branchname() if config.options.autosave and (allow_dir(dir) and not ignore_dir(dir) and vim.g.persisting == nil) + and not ignore_branch(branch) and args_check() then M.start() @@ -171,6 +204,7 @@ end function M.load(opt, dir) opt = opt or {} dir = dir or session_dir() + local branch = get_branchname() local session = opt.session or (opt.last and get_last() or get_current(dir)) @@ -185,7 +219,11 @@ function M.load(opt, dir) end end - if config.options.autosave and (allow_dir(dir) and not ignore_dir(dir)) then + if + config.options.autosave + and (allow_dir(dir) and not ignore_dir(dir)) + and not ignore_branch(branch) + then M.start() end end @@ -194,9 +232,10 @@ end ---@return nil function M.autoload() local dir = session_dir() + local branch = get_branchname() if config.options.autoload and args_check() then - if allow_dir(dir) and not ignore_dir(dir) then + if allow_dir(dir) and not ignore_dir(dir) and not ignore_branch(branch) then M.load({}, dir) end end diff --git a/lua/persisted/utils.lua b/lua/persisted/utils.lua index 677799b..cd86d8b 100644 --- a/lua/persisted/utils.lua +++ b/lua/persisted/utils.lua @@ -82,7 +82,15 @@ end ---@return boolean function M.dirs_match(dir, dirs_table) dir = vim.fn.expand(dir) - return dirs_table + return M.table_match(dir, dirs_table, function(pattern) return escape_pattern(vim.fn.expand(pattern)) end) +end + +---Check if a string matches and entry in a given table +---@param needle string +---@param heystack table +---@return boolean +function M.table_match(needle, heystack, escape_fct) + return heystack and next(vim.tbl_filter(function(pattern) if pattern.exact then -- The pattern is actually a table @@ -92,11 +100,14 @@ function M.dirs_match(dir, dirs_table) if pattern:sub(-1) == fp_sep and pattern:len() > 1 then pattern = pattern:sub(1, -2) end - return dir == pattern + return needle == pattern else - return dir:find(escape_pattern(vim.fn.expand(pattern))) + if escape_fct then + pattern = escape_fct(pattern) + end + return needle:match(pattern) end - end, dirs_table)) + end, heystack)) end ---Get the directory pattern based on OS