feat: ✨ allow/ignore dirs for save/load
This addresses #1 and allows the user to specify directories which the plugin will automatically save or load from. Alternatively, specify directories for which this behaviour will be ignoredmain
parent
b2e4162c74
commit
0669d29f22
24
README.md
24
README.md
|
|
@ -7,14 +7,14 @@ The plugin was forked from the fantastic [Persistence.nvim](https://github.com/f
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
|
|
||||||
- Automatically saves the active session under `.local/share/nvim/sessions` on exiting Neovim
|
- Automatically saves the active session under `.local/share/nvim/sessions` on exiting Neovim
|
||||||
- Simple API to restore the current or last session
|
- Supports auto saving and loading of sessions with allowed/ignored directories
|
||||||
|
- Simple API to save/stop/restore/delete/list the current session(s)
|
||||||
- Support for sessions across git branches
|
- Support for sessions across git branches
|
||||||
- Specify custom directory to save sessions
|
- Specify custom directory to save/load sessions from
|
||||||
- Stop or even delete the current session
|
|
||||||
|
|
||||||
## ⚡️ Requirements
|
## ⚡️ Requirements
|
||||||
|
|
||||||
- Neovim >= 0.5.0
|
- Neovim >= 0.6.0
|
||||||
|
|
||||||
## 📦 Installation
|
## 📦 Installation
|
||||||
|
|
||||||
|
|
@ -55,9 +55,11 @@ The plugin comes with the following defaults:
|
||||||
{
|
{
|
||||||
dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- directory where session files are saved
|
dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- directory where session files are saved
|
||||||
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 the git enabled repository
|
||||||
autosave = true, -- automatically save session files
|
autosave = true, -- automatically save session files when exiting Neovim
|
||||||
autoload = false, -- automatically load the current session on Neovim startup
|
autoload = false, -- automatically load the session for the cwd on Neovim startup
|
||||||
options = { "buffers", "curdir", "tabpages", "winsize" }, -- session options used for saving
|
options = { "buffers", "curdir", "tabpages", "winsize" }, -- session options used for saving
|
||||||
|
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
|
||||||
before_save = function() end, -- function to run before the session is saved to disk
|
before_save = function() end, -- function to run before the session is saved to disk
|
||||||
after_save = function() end, -- function to run after the session is saved to disk
|
after_save = function() end, -- function to run after the session is saved to disk
|
||||||
}
|
}
|
||||||
|
|
@ -65,13 +67,17 @@ The plugin comes with the following defaults:
|
||||||
|
|
||||||
These can be overwritten by calling the `setup` method and passing in the appropriate value.
|
These can be overwritten by calling the `setup` method and passing in the appropriate value.
|
||||||
|
|
||||||
|
> **Note:** `autosave` and `autoload` may not work if you've lazy loaded the plugin.
|
||||||
|
|
||||||
## 🚀 Usage
|
## 🚀 Usage
|
||||||
|
|
||||||
The plugin works well with others like [vim-startify](https://github.com/mhinz/vim-startify) or [dashboard](https://github.com/glepnir/dashboard-nvim). It will never restore a session automatically but the commands below, or a custom autocmd, may be used.
|
The plugin is designed to work with startup screens like [vim-startify](https://github.com/mhinz/vim-startify) or [dashboard](https://github.com/glepnir/dashboard-nvim) out of the box. It will never load a session automatically by default.
|
||||||
|
|
||||||
|
To use the plugin, the commands below may be used:
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
- `SessionStart` - Start a session. Useful if `autosave = false`
|
- `SessionStart` - Start recording a session. Useful if `autosave = false`
|
||||||
- `SessionStop` - Stop recording a session
|
- `SessionStop` - Stop recording a session
|
||||||
- `SessionSave` - Save the current session
|
- `SessionSave` - Save the current session
|
||||||
- `SessionLoad` - Load the session for the current directory and current branch if `git_use_branch = true`
|
- `SessionLoad` - Load the session for the current directory and current branch if `git_use_branch = true`
|
||||||
|
|
@ -79,6 +85,8 @@ The plugin works well with others like [vim-startify](https://github.com/mhinz/v
|
||||||
- `SessionDelete` - Delete the current session
|
- `SessionDelete` - Delete the current session
|
||||||
- `SessionToggle` - Determines whether to load, start or stop a session
|
- `SessionToggle` - Determines whether to load, start or stop a session
|
||||||
|
|
||||||
|
> **Note:** The author only binds `SessionToggle` to a keymap for simplicity.
|
||||||
|
|
||||||
### Callbacks
|
### Callbacks
|
||||||
|
|
||||||
The plugin allows for _before_ and _after_ callbacks to be executed relative to the session. This is achieved via the `before_save` and `after_save` configuration options.
|
The plugin allows for _before_ and _after_ callbacks to be executed relative to the session. This is achieved via the `before_save` and `after_save` configuration options.
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,11 @@ local M = {}
|
||||||
local defaults = {
|
local defaults = {
|
||||||
dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- directory where session files are saved
|
dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- directory where session files are saved
|
||||||
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 the git enabled repository
|
||||||
autosave = true, -- automatically save session files
|
autosave = true, -- automatically save session files when exiting Neovim
|
||||||
autoload = false, -- automatically load the session in the cwd on Neovim startup
|
autoload = false, -- automatically load the session for the cwd on Neovim startup
|
||||||
options = { "buffers", "curdir", "tabpages", "winsize" }, -- session options used for saving
|
options = { "buffers", "curdir", "tabpages", "winsize" }, -- session options used for saving
|
||||||
|
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
|
||||||
before_save = function() end, -- function to run before the session is saved to disk
|
before_save = function() end, -- function to run before the session is saved to disk
|
||||||
after_save = function() end, -- function to run after the session is saved to disk
|
after_save = function() end, -- function to run after the session is saved to disk
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,18 @@ local config = require("persisted.config")
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local e = vim.fn.fnameescape
|
local e = vim.fn.fnameescape
|
||||||
|
local echo = vim.api.nvim_echo
|
||||||
|
|
||||||
|
local echoerr = function(msg, error)
|
||||||
|
echo({
|
||||||
|
{ "[persisted.nvim]: ", "ErrorMsg" },
|
||||||
|
{ msg, "WarningMsg" },
|
||||||
|
{ error, "Normal" },
|
||||||
|
}, true, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
---Setup the plugin's commands
|
||||||
|
---@return nil
|
||||||
local function setup_commands()
|
local function setup_commands()
|
||||||
vim.cmd([[
|
vim.cmd([[
|
||||||
command! SessionStart :lua require("persisted").start()
|
command! SessionStart :lua require("persisted").start()
|
||||||
|
|
@ -16,16 +27,55 @@ local function setup_commands()
|
||||||
]])
|
]])
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_current()
|
---Check if a target directory exists in a given table
|
||||||
local pattern = "/"
|
---@param dir_target string
|
||||||
if vim.fn.has("win32") == 1 then
|
---@param dir_table table
|
||||||
pattern = "[\\:]"
|
---@return boolean
|
||||||
|
local function dirs_match(dir_target, dir_table)
|
||||||
|
for _, dir in pairs(dir_table) do
|
||||||
|
dir = string.gsub(vim.fn.expand(dir), "/+$", "")
|
||||||
|
if dir_target == dir then
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
local name = vim.fn.getcwd():gsub(pattern, "%%")
|
end
|
||||||
return config.options.dir .. name .. get_branch() .. ".vim"
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_branch()
|
---Does the current working directory allow for the auto-saving and loading?
|
||||||
|
---@return boolean
|
||||||
|
local function allow_dir()
|
||||||
|
local allowed_dirs = config.options.allowed_dirs
|
||||||
|
|
||||||
|
if allowed_dirs == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return dirs_match(vim.fn.getcwd(), allowed_dirs)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Is the current working directory ignored for auto-saving and loading?
|
||||||
|
---@return boolean
|
||||||
|
local function ignore_dir()
|
||||||
|
local ignored_dirs = config.options.ignored_dirs
|
||||||
|
|
||||||
|
if ignored_dirs == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return dirs_match(vim.fn.getcwd(), ignored_dirs)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Get the session that was saved last
|
||||||
|
---@return string
|
||||||
|
local function get_last()
|
||||||
|
local sessions = M.list()
|
||||||
|
table.sort(sessions, function(a, b)
|
||||||
|
return vim.loop.fs_stat(a).mtime.sec > vim.loop.fs_stat(b).mtime.sec
|
||||||
|
end)
|
||||||
|
return sessions[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
---Get the current Git branch
|
||||||
|
---@return string
|
||||||
|
local function get_branch()
|
||||||
local git_enabled = (vim.fn.isdirectory(vim.fn.getcwd() .. "/.git") == 1)
|
local git_enabled = (vim.fn.isdirectory(vim.fn.getcwd() .. "/.git") == 1)
|
||||||
|
|
||||||
if config.options.use_git_branch and git_enabled then
|
if config.options.use_git_branch and git_enabled then
|
||||||
|
|
@ -42,25 +92,52 @@ function get_branch()
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_last()
|
---Get the current session for the current working directory and git branch
|
||||||
local sessions = M.list()
|
---@return string
|
||||||
table.sort(sessions, function(a, b)
|
local function get_current()
|
||||||
return vim.loop.fs_stat(a).mtime.sec > vim.loop.fs_stat(b).mtime.sec
|
local pattern = "/"
|
||||||
end)
|
if vim.fn.has("win32") == 1 then
|
||||||
return sessions[1]
|
pattern = "[\\:]"
|
||||||
|
end
|
||||||
|
local name = vim.fn.getcwd():gsub(pattern, "%%")
|
||||||
|
return config.options.dir .. name .. get_branch() .. ".vim"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Setup the plugin based on the intersect of the default and the user's config
|
||||||
|
---@param opts table
|
||||||
|
---@return nil
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
config.setup(opts)
|
config.setup(opts)
|
||||||
setup_commands()
|
setup_commands()
|
||||||
if config.options.autoload then
|
if config.options.autoload and (allow_dir() and not ignore_dir()) then
|
||||||
M.load()
|
M.load()
|
||||||
end
|
end
|
||||||
if config.options.autosave then
|
if config.options.autosave and (allow_dir() and not ignore_dir() and vim.g.persisting == nil) then
|
||||||
M.start()
|
M.start()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Load a session
|
||||||
|
---@param opt table
|
||||||
|
---@return nil
|
||||||
|
function M.load(opt)
|
||||||
|
opt = opt or {}
|
||||||
|
local session = opt.last and get_last() or get_current()
|
||||||
|
|
||||||
|
if session and vim.fn.filereadable(session) ~= 0 then
|
||||||
|
local ok, result = pcall(vim.cmd, "source " .. e(session))
|
||||||
|
if not ok then
|
||||||
|
echoerr("Error loading the session! ", result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.options.autosave and (allow_dir() and not ignore_dir()) then
|
||||||
|
M.start()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Start recording a session and write it to disk when exiting Neovim
|
||||||
|
---@return nil
|
||||||
function M.start()
|
function M.start()
|
||||||
vim.cmd([[
|
vim.cmd([[
|
||||||
augroup Persisted
|
augroup Persisted
|
||||||
|
|
@ -71,6 +148,8 @@ function M.start()
|
||||||
vim.g.persisting = true
|
vim.g.persisting = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Stop recording a session
|
||||||
|
---@return nil
|
||||||
function M.stop()
|
function M.stop()
|
||||||
vim.cmd([[
|
vim.cmd([[
|
||||||
autocmd! Persisted
|
autocmd! Persisted
|
||||||
|
|
@ -79,39 +158,38 @@ function M.stop()
|
||||||
vim.g.persisting = false
|
vim.g.persisting = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Save the session to disk
|
||||||
|
---@return nil
|
||||||
function M.save()
|
function M.save()
|
||||||
config.options.before_save()
|
config.options.before_save()
|
||||||
|
|
||||||
local tmp = vim.o.sessionoptions
|
local tmp = vim.o.sessionoptions
|
||||||
vim.o.sessionoptions = table.concat(config.options.options, ",")
|
vim.o.sessionoptions = table.concat(config.options.options, ",")
|
||||||
vim.cmd("mks! " .. e(M.get_current()))
|
vim.cmd("mks! " .. e(get_current()))
|
||||||
vim.o.sessionoptions = tmp
|
vim.o.sessionoptions = tmp
|
||||||
vim.g.persisting = true
|
vim.g.persisting = true
|
||||||
|
|
||||||
config.options.after_save()
|
config.options.after_save()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Delete the current session from disk
|
||||||
|
---@return nil
|
||||||
function M.delete()
|
function M.delete()
|
||||||
local session = M.get_current()
|
local session = get_current()
|
||||||
if session and vim.loop.fs_stat(session) ~= 0 then
|
if session and vim.loop.fs_stat(session) ~= 0 then
|
||||||
M.stop()
|
M.stop()
|
||||||
vim.fn.system("rm " .. e(session))
|
vim.fn.system("rm " .. e(session))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.load(opt)
|
---List all of the sessions in the session directory
|
||||||
opt = opt or {}
|
---@return table
|
||||||
local session = opt.last and M.get_last() or M.get_current()
|
|
||||||
if session and vim.fn.filereadable(session) ~= 0 then
|
|
||||||
vim.cmd("source " .. e(session))
|
|
||||||
vim.g.persisting = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.list()
|
function M.list()
|
||||||
return vim.fn.glob(config.options.dir .. "*.vim", true, true)
|
return vim.fn.glob(config.options.dir .. "*.vim", true, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Determines whether to load, start or stop a session
|
||||||
|
---@return function
|
||||||
function M.toggle()
|
function M.toggle()
|
||||||
if vim.g.persisting == nil then
|
if vim.g.persisting == nil then
|
||||||
return M.load()
|
return M.load()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue