Persisted.nvim

Persisted.nvim

Persisted.nvim is a simple lua plugin for working with sessions in Neovim
Forked from Persistence.nvim as active development had stopped

## :sparkles: Features - Automatically saves the active session under `.local/share/nvim/sessions` on exiting Neovim - Supports sessions across multiple git branches - Supports autosaving and autoloading of sessions with allowed/ignored directories - Simple API to save/stop/restore/delete/list the current session(s) - Custom events which users can hook into for greater integration - Telescope extension to work with saved sessions ## :zap: Requirements - Neovim >= 0.8.0 ## :package: Installation Install the plugin with your preferred package manager: **[Lazy.nvim](https://github.com/folke/lazy.nvim)** ```lua -- Lua { "olimorris/persisted.nvim", config = true } ``` **[Packer](https://github.com/wbthomason/packer.nvim)** ```lua -- Lua use({ "olimorris/persisted.nvim", config = function() require("persisted").setup() end, }) ``` **[Vim Plug](https://github.com/junegunn/vim-plug)** ```vim " Vim Script Plug 'olimorris/persisted.nvim' lua << EOF require("persisted").setup { -- your configuration comes here -- or leave it empty to use the default settings -- refer to the configuration section below } EOF ``` If you wish to use session _autoloading_ alongside a dashboard plugin, it is recommended that you give this plugin a greater loading priority. With **Packer** the `after` config option can be used and in **Lazy.nvim**, the `priority` property. ### Telescope extension Ensure that the telescope extension is loaded with: ```lua require("telescope").load_extension("persisted") ``` The layout can then be customised from within Telescope: ```lua require('telescope').setup({ defaults = { … }, extensions = { persisted = { layout_config = { width = 0.55, height = 0.55 } } } }) ``` ## :rocket: Usage ### Commands The plugin comes with a number of commands: - `:SessionToggle` - Determines whether to load, start or stop a session - `:SessionStart` - Start recording a session. Useful if `autosave = false` - `:SessionStop` - Stop recording a session - `:SessionSave` - Save the current session - `:SessionLoad` - Load the session for the current directory and current branch (if `git_use_branch = true`) - `:SessionLoadLast` - Load the most recent session - `:SessionLoadFromFile` - Load a session from a given path - `:SessionDelete` - Delete the current session ### Telescope extension The Telescope extension may be opened via `:Telescope persisted`. Once opened, the available keymaps are: - `` - Source the session file - `` - Delete the session file ### Global variables The plugin sets global variables which can be utilised in your configuration: - `vim.g.persisting` - (bool) Determines if the plugin is active for the current session - `vim.g.persisted_exists` - (bool) Determines if a session exists for the current working directory - `vim.g.persisted_loaded_session` - (string) The file path to the current session ## :wrench: Configuration ### Defaults The plugin comes with the following defaults: ```lua 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 the git enabled repository 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 on_autoload_no_session = nil, -- function to run when `autoload = true` but there is no session to load 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 telescope = { -- options for the telescope extension reset_prompt_after_deletion = true, -- whether to reset prompt after session deleted }, }) ``` ### What is saved in the session? As the plugin uses Vim's `:mksession` command then you may change the `vim.o.sessionoptions` value to determine what to write into the session. Please see `:h sessionoptions` for more information. > **Note**: The author uses: > `vim.o.sessionoptions = "buffers,curdir,folds,globals,tabpages,winpos,winsize"` ### Session save location The location of the session files may be changed by altering the `save_dir` configuration option. For example: ```lua require("persisted").setup({ save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- Resolves to ~/.local/share/nvim/sessions/ }) ``` > **Note**: The plugin may be unable to find existing sessions if the `save_dir` value is changed ### Git branching One of the plugin's core features is the ability to have multiple session files for a given project, by using git branches. To enable git branching: ```lua require("persisted").setup({ use_git_branch = true, }) ``` > **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. ### Autosaving By default, the plugin will automatically save a Neovim session to disk when the `VimLeavePre` event is triggered. Autosaving can be turned off by: ```lua require("persisted").setup({ autosave = false, }) ``` Autosaving can be further controlled for certain directories by specifying `allowed_dirs` and `ignored_dirs`. There may be occasions when you do not wish to autosave; perhaps when a dashboard or a certain buftype is present. To control this, a callback function, `should_autosave`, may be used which should return a boolean value. ```lua require("persisted").setup({ should_autosave = function() -- do not autosave if the alpha dashboard is the current filetype if vim.bo.filetype == "alpha" then return false end return true end, }) ``` Of course, if you wish to manually save the session when autosaving is disabled, the `:SessionSave` command can be used. > **Note**: If `autosave = false` then the `should_autosave` callback will not be executed. ### Autoloading The plugin can be enabled to automatically load sessions when Neovim is started. Whilst off by default, this can be turned on by: ```lua require("persisted").setup({ autoload = true, }) ``` You can also provide a function to run when `autoload = true` but there is no session to be loaded: ```lua require("persisted").setup({ autoload = true, on_autoload_no_session = function() vim.notify("No existing session to load.") end }) ``` Autoloading can be further controlled for certain directories by specifying `allowed_dirs` and `ignored_dirs`. > **Note**: Autoloading will not occur if a user opens Neovim with arguments. For example: `nvim some_file.rb` ### Following current working directory There may be a need to change the working directory to quickly access files in other directories without changing the current session's name on save. This behavior can be configured with `follow_cwd = false`. By default, the session name will match the current working directory: ```lua require("persisted").setup({ follow_cwd = true, }) ``` > **Note**: If `follow_cwd = false` the session name is stored upon loading under the global variable `vim.g.persisting_session`. This variable can be manually adjusted if changes to the session name are needed. Alternatively, if `follow_cwd = true` then `vim.g.persisting_session = nil`. ### Allowed directories You may specify a table of directories for which the plugin will autosave and/or autoload from. For example: ```lua require("persisted").setup({ allowed_dirs = { "~/.dotfiles", "~/Code", }, }) ``` Specifying `~/Code` will autosave and autoload from that directory as well as all its sub-directories. > **Note**: If `allowed_dirs` is left at its default value and `autosave` and/or `autoload` are set to `true`, then the plugin will autoload/autosave from _any_ directory ### Ignored directories You may specify a table of directories for which the plugin will **never** autosave and autoload from. For example: ```lua require("persisted").setup({ ignored_dirs = { "~/.config", "~/.local/nvim" }, }) ``` Specifying `~/.config` will prevent any autosaving and autoloading from that directory as well as all its sub-directories. ### Events / Callbacks The plugin fires events at various points during its lifecycle which users can hook into: - `PersistedLoadPre` - For _before_ a session is loaded - `PersistedLoadPost` - For _after_ a session is loaded - `PersistedTelescopeLoadPre` - For _before_ a session is loaded via Telescope - `PersistedTelescopeLoadPost` - For _after_ a session is loaded via Telescope - `PersistedSavePre` - For _before_ a session is saved - `PersistedSavePost` - For _after_ a session is saved - `PersistedDeletePre` - For _before_ a session is deleted - `PersistedDeletePost` - For _after_ a session is deleted - `PersistedStateChange` - For when a session is _started_ or _stopped_ - `PersistedToggled` - For when a session is toggled For example, to ensure that the excellent [minimap](https://github.com/wfxr/minimap.vim) plugin is not saved into a session, an autocmd can be created to hook into the `PersistedSavePre` event: ```lua local group = vim.api.nvim_create_augroup("PersistedHooks", {}) vim.api.nvim_create_autocmd({ "User" }, { pattern = "PersistedSavePre", group = group, callback = function() pcall(vim.cmd, "bw minimap") end, }) ``` Another and more commonly requested example is to use the Telescope extension to load a session, saving the current session before clearing all of the open buffers. This can be achieved by utilising some of the session data that is made available to the callbacks: ```lua local group = vim.api.nvim_create_augroup("PersistedHooks", {}) vim.api.nvim_create_autocmd({ "User" }, { pattern = "PersistedTelescopeLoadPre", group = group, callback = function(session) -- Save the currently loaded session require("persisted").save({ session = vim.g.persisted_loaded_session }) -- Delete all of the open buffers vim.api.nvim_input(":%bd!") end, }) ``` The session data available differs depending on the events that are hooked into. For non-telescope events, only the session's full path is available (via `session.data`). However for telescope events, the `branch`, `name`, `file_path` and `dir_path` are available. ### Telescope extension

Telescope

The plugin contains an extension for [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) which allows the user to list all of the saved session files and source them via `:Telescope persisted`. ## :page_with_curl: License [MIT](https://github.com/olimorris/persisted.nvim/blob/main/LICENSE)