diff --git a/README.md b/README.md
index d29f3c8..5f6714a 100644
--- a/README.md
+++ b/README.md
@@ -23,8 +23,8 @@
## :sparkles: Features
- :evergreen_tree: Supports sessions across multiple git branches
-- :telescope: Telescope extension to work with saved sessions
-- :tickets: Custom events which users can hook into for tighter integration
+- :telescope: Telescope extension to manage sessions
+- :tickets: Custom events which users can hook into for tighter integrations
- :memo: Simple API to save/stop/restore/delete/list the current session(s)
- :open_file_folder: Supports autosaving and autoloading of sessions with allowed/ignored directories
- :floppy_disk: Automatically saves the active session under `.local/share/nvim/sessions` on exiting Neovim
@@ -35,7 +35,7 @@
## :package: Installation
-Install the plugin with your preferred package manager:
+Install and configure the plugin with your preferred package manager:
**[Lazy.nvim](https://github.com/folke/lazy.nvim)**
@@ -110,7 +110,7 @@ require('telescope').setup({
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`
+- `:SessionStart` - Start recording a session. Useful if `autostart = 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`)
@@ -123,12 +123,12 @@ The plugin comes with a number of commands:
-
+
-The Telescope extension may be opened via `:Telescope persisted`. The available actions are:
+The Telescope extension may be opened via `:Telescope persisted`. The default actions are:
- `` - Open/source the session file
- `` - Add/update the git branch for the session file
@@ -140,8 +140,8 @@ The Telescope extension may be opened via `:Telescope persisted`. The available
The plugin sets a number of global variables throughout its lifecycle:
- `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
+- `vim.g.persisting_session` - (string) The file path to the current session (if `follow_cwd` is false)
+- `vim.g.persisted_loaded_session` - (string) The file path to the last loaded session
## :wrench: Configuration
@@ -150,34 +150,41 @@ The plugin sets a number of global variables throughout its lifecycle:
The plugin comes with the following defaults:
```lua
-require("persisted").setup({
- log_level = "ERROR", -- One of "TRACE", "DEBUG", "ERROR"
- 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
- 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
- ignored_branches = nil, -- table of branch patterns that are ignored for auto-saving and auto-loading
+{
+ autostart = true, -- Automatically start the plugin on load?
+
+ -- Function to determine if a session should be saved
+ ---@type fun(): boolean
+ should_save = function()
+ return true
+ end,
+
+ save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- Directory where session files are saved
+
+ follow_cwd = true, -- Change the session file to match any change in the cwd?
+ use_git_branch = false, -- Include the git branch in the session file name?
+ autoload = false, -- Automatically load the session for the cwd on Neovim startup?
+
+ -- Function to run when `autoload = true` but there is no session to load
+ ---@type fun(): any
+ on_autoload_no_session = function() end,
+
+ allowed_dirs = {}, -- Table of dirs that the plugin will start and autoload from
+ ignored_dirs = {}, -- Table of dirs that are ignored for starting and autoloading
+
telescope = {
- reset_prompt = true, -- Reset the Telescope prompt after an action?
- mappings = { -- table of mappings for the Telescope extension
- change_branch = "",
- copy_session = "",
- delete_session = "",
+ mappings = { -- Mappings for managing sessions in Telescope
+ copy_session = "",
+ change_branch = "",
+ delete_session = "",
},
- icons = { -- icons displayed in the picker, set to nil to disable entirely
+ icons = { -- icons displayed in the Telescope picker
+ selected = " ",
+ dir = " ",
branch = " ",
- dir = " ",
- selected = " ",
},
},
-})
+}
```
**What is saved in the session?**
@@ -185,7 +192,7 @@ require("persisted").setup({
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,tabpages,winpos,winsize"`
+> The author uses: `vim.o.sessionoptions = "buffers,curdir,folds,globals,tabpages,winpos,winsize"`
**Session save location**
@@ -210,24 +217,27 @@ require("persisted").setup({
})
```
-**Autosaving**
+**Autostart**
-By default, the plugin will automatically save a Neovim session to disk when the `VimLeavePre` event is triggered. Autosaving can be turned off by:
+By default, the plugin will automatically start when the setup function is called. This results in a Neovim session being saved to disk when the `VimLeavePre` event is triggered. This can be disabled by:
```lua
require("persisted").setup({
- autosave = false,
+ autostart = false,
})
```
-Autosaving can be further controlled for certain directories by specifying `allowed_dirs` and `ignored_dirs`.
+Autostarting 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.
+**`should_save`**
+
+There may be occasions when you do not wish to save the session; perhaps when a dashboard or a certain filetype is present. To handle this, the `should_save` function 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
+ ---@return bool
+ should_save = function()
+ -- Do not save if the alpha dashboard is the current filetype
if vim.bo.filetype == "alpha" then
return false
end
@@ -236,10 +246,7 @@ require("persisted").setup({
})
```
-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.
+Of course, if you wish to manually save the session the `:SessionSave` command can be used.
**Autoloading**
@@ -251,7 +258,7 @@ require("persisted").setup({
})
```
-You can also provide a function to run when `autoload = true` but there is no session to be loaded:
+You can also provide a function to run when `autoload = true` and there is no session to load:
```lua
require("persisted").setup({
@@ -262,29 +269,14 @@ require("persisted").setup({
})
```
-Autoloading can be further controlled for certain directories by specifying `allowed_dirs` and `ignored_dirs`.
+Autoloading can be further controlled for directories in the `allowed_dirs` and `ignored_dirs` config tables.
-> [!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 result in autoloading but `nvim some/existing/path` or `nvim .` will.
-
-**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`.
+> [!IMPORTANT]
+> By design, the plugin will not autoload a session when any arguments are passed to Neovim such as `nvim my_file.py`
**Allowed directories**
-You may specify a table of directories for which the plugin will autosave and/or autoload from. For example:
+You may specify a table of directories for which the plugin will start and/or autoload from. For example:
```lua
require("persisted").setup({
@@ -295,14 +287,14 @@ require("persisted").setup({
})
```
-Specifying `~/Code` will autosave and autoload from that directory as well as all its sub-directories.
+Specifying `~/Code` will start 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
+> If `allowed_dirs` is left at its default value and `autostart` and/or `autoload` are set to `true`, then the plugin will start and autoload from _any_ directory
**Ignored directories**
-You may specify a table of directories for which the plugin will **never** autosave and autoload from. For example:
+You may specify a table of directories for which the plugin will **never** start and autoload from. For example:
```lua
require("persisted").setup({
@@ -330,19 +322,6 @@ 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 branches for which the plugin will **never** autosave and autoload from:
-
-```lua
-require("persisted").setup({
- ignored_branches = {
- "^master",
- "feature/%u"
- },
-})
-```
-
**Events / Callbacks**
The plugin fires events at various points during its lifecycle:
@@ -355,21 +334,19 @@ The plugin fires events at various points during its lifecycle:
- `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
+- `PersistedStart` - For when a session has _started_
+- `PersistedStop` - For when a session has _stopped_
+- `PersistedToggle` - For when a session is toggled
These events can be consumed anywhere within your configuration by utilising the `vim.api.nvim_create_autocmd` function.
A commonly requested example is to use the Telescope extension to load a session, saving the current session before clearing all of the open buffers:
```lua
-local group = vim.api.nvim_create_augroup("PersistedHooks", {})
-
-vim.api.nvim_create_autocmd({ "User" }, {
+vim.api.nvim_create_autocmd("User", {
pattern = "PersistedTelescopeLoadPre",
- group = group,
callback = function(session)
- -- Save the currently loaded session using a global variable
+ -- Save the currently loaded session using the global variable
require("persisted").save({ session = vim.g.persisted_loaded_session })
-- Delete all of the open buffers
@@ -378,33 +355,59 @@ vim.api.nvim_create_autocmd({ "User" }, {
})
```
-**Using callback data**
+**Highlights**
-When certain events are fired, session data is made available for the user to consume, for example:
+The plugin also comes with pre-defined highlight groups for the Telescope implementation:
+
+- `PersistedTelescopeSelected`
+- `PersistedTelescopeDir`
+- `PersistedTelescopeBranch`
+
+## :building_construction: Extending the Plugin
+
+The plugin has been designed to be fully extensible. All of the functions in the [init.lua](https://github.com/olimorris/persisted.nvim/blob/main/lua/persisted/init.lua) and [utils.lua](https://github.com/olimorris/persisted.nvim/blob/main/lua/persisted/utils.lua) file are public.
+
+Consider a user who wishes to autoload a session if arguments are passed to Neovim. A custom autocmd can be created which forces the autoload:
```lua
-{
- branch = "main",
- dir_path = "Code/Neovim/persisted.nvim",
- file_path = "/Users/Oli/.local/share/nvim/sessions/%Users%Oli%Code%Neovim%persisted.nvim@@main.vim",
- name = "Code/Neovim/persisted.nvim@@main",
-}
-```
+local persisted = require("persisted")
-To consume this data, use the `session.data` table in your autocmd:
+persisted.setup({
+ autoload = true
+})
-```lua
-vim.api.nvim_create_autocmd({ "User" }, {
- pattern = "PersistedLoadPost",
- group = group,
- callback = function(session)
- print(session.data.branch)
+vim.api.nvim_create_autocmd("VimEnter", {
+ nested = true,
+ callback = function()
+ -- Add more complex logic here
+ if vim.fn.argc() > 0 then
+ -- Leverage the plugin's ability to resolve allowed_dirs and ignored_dirs
+ require("persisted").autoload({ force = true })
+ end
end,
})
```
-> [!NOTE]
-> This data is available for the `PersistedLoad`, `PersistedDelete` and `PersistedTelescope` events
+Or, a user who wishes to check whether the current branch is in a table of branches to be ignored:
+
+```lua
+local persisted = require("persisted")
+local utils = require("persisted.utils")
+
+persisted.setup({
+ autostart = false,
+ use_git_branch = true,
+})
+
+local ignored_branches = {
+ "feature_branch"
+}
+
+if utils.in_table(persisted.branch(), ignored_branches) ~= nil then
+ persisted.load()
+ persisted.start()
+end
+```
## :page_with_curl: License
diff --git a/doc/persisted.nvim.txt b/doc/persisted.nvim.txt
index 1295a24..1385ae5 100644
--- a/doc/persisted.nvim.txt
+++ b/doc/persisted.nvim.txt
@@ -8,14 +8,14 @@ Table of Contents *persisted.nvim-table-of-contents*
- Installation |persisted.nvim-installation|
- Usage |persisted.nvim-usage|
- Configuration |persisted.nvim-configuration|
+ - Extending the Plugin |persisted.nvim-extending-the-plugin|
- License |persisted.nvim-license|
FEATURES *persisted.nvim-features*
-
- Supports sessions across multiple git branches
-- Telescope extension to work with saved sessions
-- Custom events which users can hook into for tighter integration
+- Telescope extension to manage sessions
+- Custom events which users can hook into for tighter integrations
- Simple API to save/stop/restore/delete/list the current session(s)
- Supports autosaving and autoloading of sessions with allowed/ignored directories
- Automatically saves the active session under `.local/share/nvim/sessions` on exiting Neovim
@@ -23,7 +23,6 @@ FEATURES *persisted.nvim-features*
REQUIREMENTS *persisted.nvim-requirements*
-
- Neovim >= 0.8.0
@@ -106,9 +105,8 @@ USAGE *persisted.nvim-usage*
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`
+- `:SessionStart` - Start recording a session. Useful if `autostart = 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`)
@@ -118,10 +116,9 @@ The plugin comes with a number of commands:
**Telescope extension**
-The Telescope extension may be opened via `:Telescope persisted`. The available
+The Telescope extension may be opened via `:Telescope persisted`. The default
actions are:
-
- `` - Open/source the session file
- `` - Add/update the git branch for the session file
- `` - Copy the session file
@@ -131,10 +128,9 @@ actions are:
The plugin sets a number of global variables throughout its lifecycle:
-
- `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
+- `vim.g.persisting_session` - (string) The file path to the current session (if `follow_cwd` is false)
+- `vim.g.persisted_loaded_session` - (string) The file path to the last loaded session
CONFIGURATION *persisted.nvim-configuration*
@@ -144,45 +140,53 @@ CONFIGURATION *persisted.nvim-configuration*
The plugin comes with the following defaults:
>lua
- require("persisted").setup({
- log_level = "ERROR", -- One of "TRACE", "DEBUG", "ERROR"
- 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
- 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
- ignored_branches = nil, -- table of branch patterns that are ignored for auto-saving and auto-loading
+ {
+ ---@type boolean
+ autostart = true, -- Automatically start the plugin on load?
+ ---@type fun(boolean)
+ should_save = nil, -- Function to determine if a session should be saved
+ ---@type string
+ save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- Directory where session files are saved
+
+ ---@type boolean
+ use_git_branch = false, -- Include the git branch in the session file name?
+
+ ---@type boolean
+ autoload = false, -- Automatically load the session for the cwd on Neovim startup?
+ ---@type fun(boolean)
+ on_autoload_no_session = nil, -- Function to run when `autoload = true` but there is no session to load
+
+ ---@type boolean
+ follow_cwd = true, -- Change session file name with changes in the cwd?
+ ---@type table
+ allowed_dirs = nil, -- Table of dirs that the plugin will start and autoload from
+ ---@type table
+ ignored_dirs = nil, -- Table of dirs that are ignored for autosaving and autoloading
+
telescope = {
- reset_prompt = true, -- Reset the Telescope prompt after an action?
- mappings = { -- table of mappings for the Telescope extension
- change_branch = "",
- copy_session = "",
- delete_session = "",
+ mappings = { -- Mappings for managing sessions in Telescope
+ change_branch = "",
+ copy_session = "",
+ delete_session = "",
},
- icons = { -- icons displayed in the picker, set to nil to disable entirely
- branch = " ",
- dir = " ",
- selected = " ",
+ icons = { -- icons displayed in the Telescope picker
+ selected = " ",
+ dir = " ",
+ branch = " ",
},
},
- })
+ }
<
**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.
+Please see |sessionoptions| for more information.
[!NOTE] The author uses: `vim.o.sessionoptions =
- "buffers,curdir,folds,tabpages,winpos,winsize"`
+ "buffers,curdir,folds,globals,tabpages,winpos,winsize"`
**Session save location**
The location of the session files may be changed by altering the `save_dir`
@@ -208,28 +212,32 @@ files for a given project, by using git branches. To enable git branching:
})
<
-**Autosaving**
+**Autostart**
-By default, the plugin will automatically save a Neovim session to disk when
-the `VimLeavePre` event is triggered. Autosaving can be turned off by:
+By default, the plugin will automatically start when the setup function is
+called. This results in a Neovim session being saved to disk when the
+`VimLeavePre` event is triggered. This can be disabled by:
>lua
require("persisted").setup({
- autosave = false,
+ autostart = false,
})
<
-Autosaving can be further controlled for certain directories by specifying
+Autostarting 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.
+**should_save**
+
+There may be occasions when you do not wish to save the session; perhaps when a
+dashboard or a certain filetype is present. To handle this, the `should_save`
+function 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
+ ---@return bool
+ should_save = function()
+ -- Do not save if the alpha dashboard is the current filetype
if vim.bo.filetype == "alpha" then
return false
end
@@ -238,12 +246,9 @@ function, `should_autosave`, may be used which should return a boolean value.
})
<
-Of course, if you wish to manually save the session when autosaving is
-disabled, the `:SessionSave` command can be used.
+Of course, if you wish to manually save the session 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
@@ -255,8 +260,8 @@ started. Whilst off by default, this can be turned on by:
})
<
-You can also provide a function to run when `autoload = true` but there is no
-session to be loaded:
+You can also provide a function to run when `autoload = true` and there is no
+session to load:
>lua
require("persisted").setup({
@@ -267,37 +272,16 @@ session to be loaded:
})
<
-Autoloading can be further controlled for certain directories by specifying
-`allowed_dirs` and `ignored_dirs`.
+Autoloading can be further controlled for directories in the `allowed_dirs` and
+`ignored_dirs` config tables.
- [!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 result in autoloading but `nvim
- some/existing/path` or `nvim .` will.
-**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`.
+ [!IMPORTANT] By design, the plugin will not autoload a session when any
+ arguments are passed to Neovim such as `nvim my_file.py`
**Allowed directories**
-You may specify a table of directories for which the plugin will autosave
-and/or autoload from. For example:
+You may specify a table of directories for which the plugin will start and/or
+autoload from. For example:
>lua
require("persisted").setup({
@@ -308,17 +292,17 @@ and/or autoload from. For example:
})
<
-Specifying `~/Code` will autosave and autoload from that directory as well as
-all its sub-directories.
+Specifying `~/Code` will start 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
+ [!NOTE] If `allowed_dirs` is left at its default value and `autostart` and/or
+ `autoload` are set to `true`, then the plugin will start and autoload from
+ _any_ directory
**Ignored directories**
You may specify a table of directories for which the plugin will **never**
-autosave and autoload from. For example:
+start and autoload from. For example:
>lua
require("persisted").setup({
@@ -351,25 +335,10 @@ 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 branches for which the
-plugin will **never** autosave and autoload from:
-
->lua
- require("persisted").setup({
- ignored_branches = {
- "^master",
- "feature/%u"
- },
- })
-<
-
**Events / Callbacks**
The plugin fires events at various points during its lifecycle:
-
- `PersistedLoadPre` - For _before_ a session is loaded
- `PersistedLoadPost` - For _after_ a session is loaded
- `PersistedTelescopeLoadPre` - For _before_ a session is loaded via Telescope
@@ -378,8 +347,9 @@ The plugin fires events at various points during its lifecycle:
- `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
+- `PersistedStart` - For when a session has _started_
+- `PersistedStop` - For when a session has _stopped_
+- `PersistedToggle` - For when a session is toggled
These events can be consumed anywhere within your configuration by utilising
the `vim.api.nvim_create_autocmd` function.
@@ -388,13 +358,10 @@ A commonly requested example is to use the Telescope extension to load a
session, saving the current session before clearing all of the open buffers:
>lua
- local group = vim.api.nvim_create_augroup("PersistedHooks", {})
-
- vim.api.nvim_create_autocmd({ "User" }, {
+ vim.api.nvim_create_autocmd("User", {
pattern = "PersistedTelescopeLoadPre",
- group = group,
callback = function(session)
- -- Save the currently loaded session using a global variable
+ -- Save the currently loaded session using the global variable
require("persisted").save({ session = vim.g.persisted_loaded_session })
-- Delete all of the open buffers
@@ -403,35 +370,69 @@ session, saving the current session before clearing all of the open buffers:
})
<
-**Using callback data**
+**Highlights**
-When certain events are fired, session data is made available for the user to
-consume, for example:
+The plugin also comes with pre-defined highlight groups for the Telescope
+implementation:
+
+- `PersistedTelescopeSelected`
+- `PersistedTelescopeDir`
+- `PersistedTelescopeBranch`
+
+
+EXTENDING THE PLUGIN *persisted.nvim-extending-the-plugin*
+
+The plugin has been designed to be fully extensible. All of the functions in
+the init.lua
+
+and utils.lua
+
+file are public.
+
+Consider a user who wishes to autoload a session if arguments are passed to
+Neovim. A custom autocmd can be created which forces the autoload:
>lua
- {
- branch = "main",
- dir_path = "Code/Neovim/persisted.nvim",
- file_path = "/Users/Oli/.local/share/nvim/sessions/%Users%Oli%Code%Neovim%persisted.nvim@@main.vim",
- name = "Code/Neovim/persisted.nvim@@main",
- }
-<
-
-To consume this data, use the `session.data` table in your autocmd:
-
->lua
- vim.api.nvim_create_autocmd({ "User" }, {
- pattern = "PersistedLoadPost",
- group = group,
- callback = function(session)
- print(session.data.branch)
+ local persisted = require("persisted")
+
+ persisted.setup({
+ autoload = true
+ })
+
+ vim.api.nvim_create_autocmd("VimEnter", {
+ nested = true,
+ callback = function()
+ -- Add more complex logic here
+ if vim.fn.argc() > 0 then
+ -- Leverage the plugin's ability to resolve allowed_dirs and ignored_dirs
+ require("persisted").autoload({ force = true })
+ end
end,
})
<
+Or, a user who wishes to check whether the current branch is in an a table of
+branches to be ignored:
+
+>lua
+ local persisted = require("persisted")
+ local utils = require("persisted.utils")
+
+ persisted.setup({
+ autostart = false,
+ use_git_branch = true,
+ })
+
+ local ignored_branches = {
+ "feature_branch"
+ }
+
+ if utils.in_table(persisted.branch(), ignored_branches) ~= nil then
+ persisted.load()
+ persisted.start()
+ end
+<
- [!NOTE] This data is available for the `PersistedLoad`, `PersistedDelete` and
- `PersistedTelescope` events
LICENSE *persisted.nvim-license*
diff --git a/lua/persisted/config.lua b/lua/persisted/config.lua
index 2287942..c811aa5 100644
--- a/lua/persisted/config.lua
+++ b/lua/persisted/config.lua
@@ -1,46 +1,35 @@
-local M = {}
+return {
+ autostart = true, -- Automatically start the plugin on load?
-local defaults = {
- log_level = "ERROR", -- One of "TRACE", "DEBUG", "ERROR"
- 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
+ -- Function to determine if a session should be saved
+ ---@type fun(): boolean
+ should_save = function()
+ return true
+ end,
- 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
+ save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- Directory where session files are saved
- 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)
+ follow_cwd = true, -- Change the session file to match any change in the cwd?
+ use_git_branch = false, -- Include the git branch in the session file name?
+ autoload = false, -- Automatically load the session for the cwd on Neovim startup?
- 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
+ -- Function to run when `autoload = true` but there is no session to load
+ ---@type fun(): any
+ on_autoload_no_session = function() end,
- 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
+ allowed_dirs = {}, -- Table of dirs that the plugin will start and autoload from
+ ignored_dirs = {}, -- Table of dirs that are ignored for starting and autoloading
telescope = {
- reset_prompt = true, -- Reset prompt after a telescope action?
- --TODO: We should add a deprecation notice for the old API here
- mappings = {
- change_branch = "",
- copy_session = "",
- delete_session = "",
+ mappings = { -- Mappings for managing sessions in Telescope
+ copy_session = "",
+ change_branch = "",
+ delete_session = "",
},
- icons = { -- icons displayed in the picker
+ icons = { -- icons displayed in the Telescope picker
+ selected = " ",
+ dir = " ",
branch = " ",
- dir = " ",
- selected = " ",
},
},
}
-
-M.options = {}
-
-function M.setup(opts)
- M.options = vim.tbl_deep_extend("force", defaults, opts or {})
- vim.fn.mkdir(M.options.save_dir, "p")
-end
-
-return M
diff --git a/lua/persisted/deprecate.lua b/lua/persisted/deprecate.lua
deleted file mode 100644
index b8b8d30..0000000
--- a/lua/persisted/deprecate.lua
+++ /dev/null
@@ -1,38 +0,0 @@
----[[
---Courtesy of the awesome work in Nightfox.nvim
---https://github.com/EdenEast/nightfox.nvim/blob/main/lua/nightfox/lib/deprecation.lua
---]
-local M = {
- _list = { { "[Persisted.nvim]\n", "Question" }, { "The following have been " }, { "deprecated:\n", "WarningMsg" } },
- _has_registered = false,
-}
-
-function M.write(...)
- for _, e in ipairs({ ... }) do
- table.insert(M._list, type(e) == "string" and { e } or e)
- end
-
- M._list[#M._list][1] = M._list[#M._list][1] .. "\n"
-
- if not M._has_registered then
- vim.cmd([[
- augroup PersistedDeprecations
- au!
- autocmd VimEnter * ++once lua require("persisted.deprecate").flush()
- augroup END
- ]])
- M._has_registered = true
- end
-end
-
-function M.flush()
- M.write(
- "----------\n",
- "See ",
- { "https://github.com/olimorris/persisted.nvim/issues/51", "Title" },
- " for more information."
- )
- vim.api.nvim_echo(M._list, true, {})
-end
-
-return M
diff --git a/lua/persisted/init.lua b/lua/persisted/init.lua
index dfe46d0..3676e02 100644
--- a/lua/persisted/init.lua
+++ b/lua/persisted/init.lua
@@ -1,410 +1,216 @@
-local config = require("persisted.config")
-local log = require("persisted.log")
local utils = require("persisted.utils")
-local uv = vim.uv or vim.loop
local M = {}
+local config
local e = vim.fn.fnameescape
+local uv = vim.uv or vim.loop
----Escapes special characters before performing string substitution
----@param str string
----@param pattern string
----@param replace string
----@param n? integer
----@return string
----@return integer
-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)
+---Fire an event
+---@param event string
+function M.fire(event)
+ vim.api.nvim_exec_autocmds("User", { pattern = "Persisted" .. event })
end
----Gets the directory from the file/path argument passed to Neovim if there's
----exactly one and it resolves to a valid directory
----@return string|nil
-local function args_path()
- if vim.fn.argc() ~= 1 then
- return nil
+---Get the current session for the cwd and git branch
+---@param opts? {branch?: boolean}
+---@return string
+function M.current(opts)
+ opts = opts or {}
+ local name = vim.fn.getcwd():gsub("[\\/:]+", "%%")
+
+ if config.use_git_branch and opts.branch ~= false then
+ local branch = M.branch()
+ if branch then
+ name = name .. "@@" .. branch:gsub("[\\/:]+", "%%")
+ end
end
- -- Use expand() to resolve '~' and use fs_realpath to resolve both '.' and
- -- relative paths passed as arguments. Note that argv() will only ever return
- -- paths/files passed as arguments and does not include other
- -- parameters/arguments. fs_realpath() returns nil if the path doesn't exist.
- -- Use isdirectory to validate it's a directory and not a file.
- local dir = uv.fs_realpath(vim.fn.expand(vim.fn.argv(0)))
- if dir ~= nil and vim.fn.isdirectory(dir) ~= 0 then
- return dir
+ return config.save_dir .. name .. ".vim"
+end
+
+---Automatically load the session for the current dir
+---@param opts? { force?: boolean }
+function M.autoload(opts)
+ opts = opts or {}
+
+ if not opts.force and (vim.fn.argc() > 0 or vim.g.started_with_stdin) then
+ return
+ end
+
+ if config.autoload and M.allowed_dir() then
+ M.load({ autoload = true })
end
- return nil
end
----Check any arguments passed to Neovim and verify if they're a directory
+---Load a session
+---@param opts? { last?: boolean, autoload?: boolean, session?: string }
+function M.load(opts)
+ opts = opts or {}
+
+ local session
+
+ if opts.last then
+ session = M.last()
+ elseif opts.session then
+ session = opts.session
+ else
+ session = M.current()
+ if vim.fn.filereadable(session) == 0 then
+ session = M.current({ branch = false })
+ end
+ end
+
+ if session and vim.fn.filereadable(session) ~= 0 then
+ vim.g.persisting_session = not config.follow_cwd and session or nil
+ vim.g.persisted_loaded_session = session
+ M.fire("LoadPre")
+ vim.cmd("silent! source " .. e(session))
+ M.fire("LoadPost")
+ elseif opts.autoload and type(config.on_autoload_no_session) == "function" then
+ config.on_autoload_no_session()
+ end
+
+ if config.autostart and M.allowed_dir() then
+ M.start()
+ end
+end
+
+---Start a session
+function M.start()
+ vim.api.nvim_create_autocmd("VimLeavePre", {
+ group = vim.api.nvim_create_augroup("Persisted", { clear = true }),
+ callback = function()
+ M.save()
+ end,
+ })
+
+ vim.g.persisting = true
+ M.fire("Start")
+end
+
+---Stop a session
+function M.stop()
+ vim.g.persisting = false
+ pcall(vim.api.nvim_del_augroup_by_name, "Persisted")
+ M.fire("Stop")
+end
+
+---Save the session
+---@param opts? { force?: boolean, session?: string }
+function M.save(opts)
+ opts = opts or {}
+
+ -- Do not save the session if should_save evals to false...unless it's forced
+ if type(config.should_save) == "function" and not config.should_save() and not opts.force then
+ return
+ end
+
+ M.fire("SavePre")
+ vim.cmd("mks! " .. e(opts.session or vim.g.persisting_session or M.current()))
+ vim.cmd("sleep 10m")
+ M.fire("SavePost")
+end
+
+---Delete the current session
+---@param opts? { session?: string }
+function M.delete(opts)
+ opts = opts or {}
+ local session = opts.session or M.current()
+
+ if session and uv.fs_stat(session) ~= 0 then
+ M.fire("DeletePre")
+
+ vim.schedule(function()
+ M.stop()
+ vim.fn.system("rm " .. e(session))
+ end)
+
+ M.fire("DeletePost")
+ end
+end
+
+---Get the current Git branch
+---@return string?
+function M.branch()
+ if uv.fs_stat(".git") then
+ local branch = vim.fn.systemlist("git branch --show-current")[1]
+ return vim.v.shell_error == 0 and branch or nil
+ end
+end
+
+---Determines whether to load, start or stop a session
+function M.toggle()
+ M.fire("Toggle")
+
+ if vim.g.persisting == nil then
+ return M.load()
+ end
+
+ if vim.g.persisting then
+ return M.stop()
+ end
+
+ return M.start()
+end
+
+---Allow autosaving and autoloading for the given dir?
+---@param opts? {dir?: string}
---@return boolean
-local function args_check()
- -- Args are valid if a single directory was resolved or if no args were used.
- return args_path() ~= nil or vim.fn.argc() == 0
-end
-
----Get the directory to be used for the session
----@return string
-local function session_dir()
- -- Use specified directory from arguments or the working directory otherwise.
- return args_path() or vim.fn.getcwd()
-end
-
----Does the current working directory allow for the auto-saving and loading?
----@param dir string Directory to be used for the session
----@return boolean
-local function allow_dir(dir)
- local allowed_dirs = config.options.allowed_dirs
-
- if allowed_dirs == nil then
+function M.allowed_dir(opts)
+ if next(config.allowed_dirs) == nil and next(config.ignored_dirs) == nil then
return true
end
- return utils.dirs_match(dir, allowed_dirs)
+ opts = opts or {}
+ local dir = opts.dir or vim.fn.getcwd()
+
+ return utils.dirs_match(dir, config.allowed_dirs) and not utils.dirs_match(dir, config.ignored_dirs)
end
----Is the current working directory ignored for auto-saving and loading?
----@param dir string Directory to be used for the session
----@return boolean
-local function ignore_dir(dir)
- local ignored_dirs = config.options.ignored_dirs
-
- if ignored_dirs == nil then
- return false
- end
-
- return utils.dirs_match(dir, ignored_dirs)
-end
-
----Is the current branch ignored for auto-saving and loading?
----@param branch? string Branch to be used for the session
----@return boolean
-local function ignore_branch(branch)
- local ignored_branches = config.options.ignored_branches
-
- if not branch or 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()
- local sessions = vim.fn.glob(config.options.save_dir .. "*.vim", true, true)
+---Get an ordered list of sessions, sorted by modified time
+---@return string[]
+function M.list()
+ local sessions = vim.fn.glob(config.save_dir .. "*.vim", true, true)
table.sort(sessions, function(a, b)
return uv.fs_stat(a).mtime.sec > uv.fs_stat(b).mtime.sec
end)
- return sessions[1]
+ return sessions
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
-function M.get_branch(dir)
- dir = dir or session_dir()
-
- if config.options.use_git_branch then
- if uv.fs_stat(".git") then
- local git_branch = vim.fn.systemlist("git branch --show-current")[1]
-
- if vim.v.shell_error == 0 then
- local branch = config.options.branch_separator .. git_branch:gsub("/", "%%")
- local branch_session = config.options.save_dir .. dir:gsub(utils.get_dir_pattern(), "%%") .. branch .. ".vim"
-
- -- Try to load the session for the current branch
- if vim.fn.filereadable(branch_session) ~= 0 then
- return branch
- else
- log:debug("Trying to load a session for branch: %s", config.options.default_branch)
- log:error("Could not load a session for branch: %s", git_branch[1])
- vim.g.persisted_branch_session = branch_session
- return config.options.branch_separator .. config.options.default_branch
- end
- end
- end
- end
-end
-
----Get the current session for the current working directory and git branch
----@param dir string Directory to be used for the session
+---Get the last session that was saved
---@return string
-local function get_current(dir)
- local name = dir:gsub(utils.get_dir_pattern(), "%%")
- local branch = M.get_branch(dir)
-
- return config.options.save_dir .. name .. (branch or "") .. ".vim"
-end
-
----Determine if a session for the current wording directory, exists
----@param dir? string Directory to be used for the session
----@return boolean
-function M.session_exists(dir)
- dir = dir or session_dir()
-
- return vim.fn.filereadable(get_current(dir)) ~= 0
+function M.last()
+ return M.list()[1]
end
---Setup the plugin
---@param opts? table
----@return nil
function M.setup(opts)
- config.setup(opts)
+ -- Account for old config options
+ if opts and opts.autosave then
+ opts.autostart = opts.autosave
+ end
+ if opts and opts.should_autosave then
+ opts.should_save = opts.should_autosave
+ end
+ if opts and opts.allowed_dirs == nil then
+ opts.allowed_dirs = {}
+ end
+ if opts and opts.ignored_dirs == nil then
+ opts.ignored_dirs = {}
+ end
- log.set_root(log.new({
- handlers = {
- {
- type = "echo",
- level = vim.log.levels.WARN,
- },
- {
- type = "file",
- filename = "persisted.log",
- level = vim.log.levels[config.options.log_level],
- },
- },
- }))
+ config = vim.tbl_deep_extend("force", require("persisted.config"), opts or {})
+ M.config = config
- local dir = session_dir()
- local branch = get_branchname()
+ vim.fn.mkdir(config.save_dir, "p")
- 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
- log:trace("Starting session")
+ if config.autostart and M.allowed_dir() and vim.g.persisting == nil then
M.start()
end
end
----Load a session
----@param opt? table
----@param dir? string Directory to be used for the session
----@return nil
-function M.load(opt, dir)
- opt = opt or {}
- dir = dir or session_dir()
-
- local branch
- local session
- if opt.session then
- session = opt.session
- local session_data = utils.make_session_data(session)
- branch = session_data and session_data.branch or ""
- log:trace("Session branch %s", branch)
- log:trace("Session data %s", session_data)
- if not branch then
- vim.notify(string.format("[Persisted.nvim]: Invalid session file %s", session), vim.log.levels.WARN)
- end
- else
- branch = get_branchname()
- session = opt.last and get_last() or get_current(dir)
- log:trace("Session branch: %s", branch)
- end
-
- if session then
- if vim.fn.filereadable(session) ~= 0 then
- vim.g.persisting_session = not config.options.follow_cwd and session or nil
- log:trace("Session load: %s", session)
- utils.load_session(session, config.options.silent)
- elseif type(config.options.on_autoload_no_session) == "function" then
- log:trace("No session to load")
- config.options.on_autoload_no_session()
- end
- end
-
- dir = session_dir()
- if config.options.autosave and (allow_dir(dir) and not ignore_dir(dir)) and not ignore_branch(branch) then
- M.start()
- end
-end
-
----Automatically load the session for the current dir
----@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) and not ignore_branch(branch) then
- log:trace("Autoloading from %s", dir)
- M.load({}, dir)
- end
- end
-end
-
----Start recording a session
----@return nil
-function M.start()
- vim.g.persisting = true
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedStateChange", data = { action = "start" } })
-end
-
----Stop recording a session
----@return nil
-function M.stop()
- vim.g.persisting = false
- vim.g.persisting_session = nil
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedStateChange", data = { action = "stop" } })
-end
-
----Write the session to disk
----@param session string
----@return nil
-local function write(session)
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedSavePre" })
- vim.cmd("mks! " .. e(session))
- vim.g.persisting = true
- log:trace("Session saved")
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedSavePost" })
-end
-
----Save the session
----@param opt? table
----@param dir? string Directory to be used for the session
----@return nil
-function M.save(opt, dir)
- opt = opt or {}
- dir = dir or session_dir()
-
- if not opt.session then
- -- Do not save the session if the user has manually stopped it...unless it's forced
- if (vim.g.persisting == false or vim.g.persisting == nil) and not opt.force then
- return
- end
-
- -- Do not save the session if autosave is turned off...unless it's forced
- if not config.options.autosave and not opt.force then
- return
- end
-
- -- Do not save the session if the callback returns false...unless it's forced
- if
- not opt.force
- and type(config.options.should_autosave) == "function"
- and not config.options.should_autosave()
- then
- return
- end
- end
-
- local session = opt.session or (vim.g.persisted_branch_session or vim.g.persisting_session or get_current(dir))
- write(session)
-end
-
----Delete the current session
----@param dir? string Directory to be used for the session
----@return nil
-function M.delete(dir)
- dir = dir or session_dir()
- local session = get_current(dir)
-
- if session and uv.fs_stat(session) ~= 0 then
- local session_data = utils.make_session_data(session)
-
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedDeletePre", data = session_data })
-
- vim.schedule(function()
- log:trace("Deleting session %s", session)
- M.stop()
- vim.fn.system("rm " .. e(session))
- end)
-
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedDeletePost", data = session_data })
- end
-end
-
----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
-function M.toggle(dir)
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedToggled" })
-
- dir = dir or session_dir()
-
- if vim.g.persisting == nil then
- log:trace("Toggling load")
- return M.load({}, dir)
- end
-
- if vim.g.persisting then
- log:trace("Toggling stop")
- return M.stop()
- end
-
- log:trace("Toggling start")
- return M.start()
-end
-
----List all of the sessions
----@return table
-function M.list()
- local save_dir = config.options.save_dir
- local session_files = vim.fn.glob(save_dir .. "*.vim", true, true)
- local branch_separator = config.options.branch_separator
- local dir_separator = utils.get_dir_pattern()
-
- local sessions = {}
- for _, session in pairs(session_files) do
- local session_name = escape_pattern(session, save_dir, "")
- :gsub("%%", dir_separator)
- :gsub(vim.fn.expand("~"), dir_separator)
- :gsub("//", "")
- :sub(1, -5)
-
- if vim.fn.has("win32") == 1 then
- -- format drive letter (no trailing separator)
- session_name = escape_pattern(session_name, dir_separator, ":", 1)
- -- format remaining filepath separator(s)
- session_name = escape_pattern(session_name, dir_separator, "\\")
- end
-
- local branch, dir_path
-
- if string.find(session_name, branch_separator, 1, true) then
- local splits = vim.split(session_name, branch_separator, { plain = true })
- branch = table.remove(splits, #splits)
- dir_path = vim.fn.join(splits, branch_separator)
- else
- dir_path = session_name
- end
-
- table.insert(sessions, {
- ["name"] = session_name,
- ["file_path"] = session,
- ["branch"] = branch,
- ["dir_path"] = dir_path,
- })
- end
-
- return sessions
-end
-
return M
diff --git a/lua/persisted/log.lua b/lua/persisted/log.lua
deleted file mode 100644
index 6ca9a25..0000000
--- a/lua/persisted/log.lua
+++ /dev/null
@@ -1,280 +0,0 @@
----@type boolean
-local is_windows = vim.loop.os_uname().version:match("Windows")
-
----@type string
-local sep = is_windows and "\\" or "/"
-
----@return string
-local join = function(...)
- local joined = table.concat({ ... }, sep)
- if is_windows then
- joined = joined:gsub("\\\\+", "\\")
- else
- joined = joined:gsub("//+", "/")
- end
- return joined
-end
-
----@class LogHandler
----@field type string
----@field level integer
----@field formatter? fun(level: integer, msg: string, ...: any)
----@field handle? fun(level: integer, text: string)
-local LogHandler = {}
-
-local levels_reverse = {}
-for k, v in pairs(vim.log.levels) do
- levels_reverse[v] = k
-end
-
-function LogHandler.new(opts)
- vim.validate({
- type = { opts.type, "s" },
- handle = { opts.handle, "f" },
- formatter = { opts.formatter, "f" },
- level = { opts.level, "n", true },
- })
- return setmetatable({
- type = opts.type,
- handle = opts.handle,
- formatter = opts.formatter,
- level = opts.level or vim.log.levels.INFO,
- }, { __index = LogHandler })
-end
-
-function LogHandler:log(level, msg, ...)
- if self.level <= level then
- local text = self.formatter(level, msg, ...)
- self.handle(level, text)
- end
-end
-
-local function default_formatter(level, msg, ...)
- local args = vim.F.pack_len(...)
- for i = 1, args.n do
- local v = args[i]
- if type(v) == "table" then
- args[i] = vim.inspect(v)
- elseif v == nil then
- args[i] = "nil"
- end
- end
- local ok, text = pcall(string.format, msg, vim.F.unpack_len(args))
- if ok then
- local str_level = levels_reverse[level]
- return string.format("[%s] %s\n%s", str_level, os.date("%Y-%m-%d %H:%M:%S"), text)
- else
- return string.format("[ERROR] error formatting log line: '%s' args %s", msg, vim.inspect(args))
- end
-end
-
----@param opts table
----@return LogHandler
-local function create_file_handler(opts)
- vim.validate({
- filename = { opts.filename, "s" },
- })
- local ok, stdpath = pcall(vim.fn.stdpath, "log")
- if not ok then
- stdpath = vim.fn.stdpath("cache")
- end
- local filepath = join(stdpath, opts.filename)
- local logfile, openerr = io.open(filepath, "a+")
- if not logfile then
- local err_msg = string.format("Failed to open the CodeCompanion log file: %s", openerr)
- vim.notify(err_msg, vim.log.levels.ERROR)
- opts.handle = function() end
- else
- opts.handle = function(level, text)
- logfile:write(text)
- logfile:write("\n")
- logfile:flush()
- end
- end
- return LogHandler.new(opts)
-end
-
----@param opts table
----@return LogHandler
-local function create_notify_handler(opts)
- opts.handle = function(level, text)
- vim.notify(text, level)
- end
- return LogHandler.new(opts)
-end
-
----@param opts table
----@return LogHandler
-local function create_echo_handler(opts)
- opts.handle = function(level, text)
- local hl = "Normal"
- if level == vim.log.levels.ERROR then
- hl = "DiagnosticError"
- elseif level == vim.log.levels.WARN then
- hl = "DiagnosticWarn"
- end
- vim.api.nvim_echo({ { text, hl } }, true, {})
- end
- return LogHandler.new(opts)
-end
-
----@return LogHandler
-local function create_null_handler()
- return LogHandler.new({
- formatter = function() end,
- handle = function() end,
- })
-end
-
----@param opts table
----@return LogHandler
-local function create_handler(opts)
- vim.validate({
- type = { opts.type, "s" },
- })
- if not opts.formatter then
- opts.formatter = default_formatter
- end
- if opts.type == "file" then
- return create_file_handler(opts)
- elseif opts.type == "notify" then
- return create_notify_handler(opts)
- elseif opts.type == "echo" then
- return create_echo_handler(opts)
- else
- vim.notify(string.format("Unknown log handler %s", opts.type), vim.log.levels.ERROR)
- return create_null_handler()
- end
-end
-
----@class Logger
----@field handlers LogHandler[]
-local Logger = {}
-
----@class LoggerArgs
----@field handlers LogHandler[]
----@field level nil|integer
-
----@param opts LoggerArgs
-function Logger.new(opts)
- vim.validate({
- handlers = { opts.handlers, "t" },
- level = { opts.level, "n", true },
- })
- local handlers = {}
- for _, defn in ipairs(opts.handlers) do
- table.insert(handlers, create_handler(defn))
- end
- local log = setmetatable({
- handlers = handlers,
- }, { __index = Logger })
- if opts.level then
- log:set_level(opts.level)
- end
- return log
-end
-
----@param level integer
-function Logger:set_level(level)
- for _, handler in ipairs(self.handlers) do
- handler.level = level
- end
-end
-
----@return LogHandler[]
-function Logger:get_handlers()
- return self.handlers
-end
-
----@param level integer
----@param msg string
----@param ... any[]
-function Logger:log(level, msg, ...)
- for _, handler in ipairs(self.handlers) do
- handler:log(level, msg, ...)
- end
-end
-
----@param msg string
----@param ... any
-function Logger:trace(msg, ...)
- self:log(vim.log.levels.TRACE, msg, ...)
-end
-
----@param msg string
----@param ... any
-function Logger:debug(msg, ...)
- self:log(vim.log.levels.DEBUG, msg, ...)
-end
-
----@param msg string
----@param ... any
-function Logger:info(msg, ...)
- self:log(vim.log.levels.INFO, msg, ...)
-end
-
----@param msg string
----@param ... any
-function Logger:warn(msg, ...)
- self:log(vim.log.levels.WARN, msg, ...)
-end
-
----@param msg string
----@param ... any
-function Logger:error(msg, ...)
- self:log(vim.log.levels.ERROR, msg, ...)
-end
-
----@generic T : any
----@param cb T
----@param message nil|string
----@return T
-function Logger:wrap_cb(cb, message)
- return function(err, ...)
- if err then
- self:error(message or "Error: %s", err)
- end
- return cb(err, ...)
- end
-end
-
-local root = Logger.new({
- handlers = {
- {
- type = "echo",
- level = vim.log.levels.WARN,
- },
- },
-})
-
----@class Logger
-local M = {}
-
-M.new = Logger.new
-
-M.get_logfile = function()
- local ok, stdpath = pcall(vim.fn.stdpath, "log")
- if not ok then
- stdpath = vim.fn.stdpath("cache")
- end
-
- return join(stdpath, "persisted.log")
-end
-
----@param logger Logger
-M.set_root = function(logger)
- root = logger
-end
-
----@return Logger
-M.get_root = function()
- return root
-end
-
-setmetatable(M, {
- __index = function(_, key)
- return root[key]
- end,
-})
-
-return M
diff --git a/lua/persisted/utils.lua b/lua/persisted/utils.lua
index c89ced8..7418c9c 100644
--- a/lua/persisted/utils.lua
+++ b/lua/persisted/utils.lua
@@ -1,23 +1,19 @@
local M = {}
-local e = vim.fn.fnameescape
-local fp_sep = vim.loop.os_uname().sysname:lower():match("windows") and "\\" or "/" -- \ for windows, mac and linux both use \
----Print an error message
---@param msg string
---@param error string
---@return string
-local function echoerr(msg, error)
- vim.api.nvim_echo({
- { "[Persisted.nvim]: ", "ErrorMsg" },
- { msg, "WarningMsg" },
- { error, "Normal" },
- }, true, {})
+---Get the directory pattern based on OS
+---@return string
+function M.dir_pattern()
+ local pattern = "/"
+ if vim.fn.has("win32") == 1 then
+ pattern = "[\\:]"
+ end
+ return pattern
end
--- Escape special pattern matching characters in a string
---@param input string
---@return string
-local function escape_pattern(input)
+function M.escape_dir_pattern(input)
local magic_chars = { "%", "(", ")", ".", "+", "-", "*", "?", "[", "^", "$" }
for _, char in ipairs(magic_chars) do
@@ -27,117 +23,47 @@ local function escape_pattern(input)
return input
end
----Form a table of session data
----@param session string
----@return table|nil
-function M.make_session_data(session)
- local config = require("persisted.config").options
-
- local home = os.getenv("HOME") or os.getenv("USERPROFILE") or ""
-
- -- Split the session string into path and branch parts
- local separator_index = session:find(config.branch_separator)
- local branch = ""
- if separator_index then
- branch = session:sub(separator_index + 2):gsub("%.vim$", ""):gsub("%%", "/")
- end
-
- -- Removing the home directory from the path and cleaning leading `/`
- local name = session:gsub(config.save_dir, ""):gsub("%%", "/"):gsub(home, "")
- -- Remove the .vim extension
- name = name:sub(1, #name - 4)
- if name:sub(1, 1) == "/" then
- name = name:sub(2)
- end
-
- local dir_path = name:gsub(branch, ""):gsub(config.branch_separator, ""):gsub(home, "")
-
- return {
- name = name,
- dir_path = dir_path,
- file_path = session,
- branch = branch,
- }
-end
-
---- Get the last element in a table
----@param table table
----@return string
-function M.get_last_item(table)
- local last
- for _, _ in pairs(table) do
- last = #table - 0
- end
- return table[last]
-end
-
---Check if a target directory exists in a given table
---@param dir string
---@param dirs_table table
---@return boolean
function M.dirs_match(dir, dirs_table)
dir = vim.fn.expand(dir)
- return M.table_match(dir, dirs_table, function(pattern)
- return escape_pattern(vim.fn.expand(pattern))
+
+ local match = M.in_table(dir, dirs_table, function(pattern)
+ return M.escape_dir_pattern(vim.fn.expand(pattern))
end)
+
+ return match
end
---Check if a string matches and entry in a given table
----@param needle string
----@param heystack table
+---@param val string
+---@param tbl table
+---@param callback function
---@return boolean
-function M.table_match(needle, heystack, escape_fct)
- if needle == nil then
+function M.in_table(val, tbl, callback)
+ if val == nil then
return false
end
- return heystack
+
+ return tbl
and next(vim.tbl_filter(function(pattern)
if pattern.exact then
- -- The pattern is actually a table
pattern = pattern[1]
-- Stripping off the trailing backslash that a user might put here,
-- but only if we aren't looking at the root directory
- if pattern:sub(-1) == fp_sep and pattern:len() > 1 then
+ if pattern:sub(-1) == M.dir_pattern() and pattern:len() > 1 then
pattern = pattern:sub(1, -2)
end
- return needle == pattern
+ return val == pattern
else
- if escape_fct then
- pattern = escape_fct(pattern)
+ if callback and type(callback) == "function" then
+ pattern = callback(pattern)
end
- return needle:match(pattern)
+ return val:match(pattern)
end
- end, heystack))
-end
-
----Get the directory pattern based on OS
----@return string
-function M.get_dir_pattern()
- local pattern = "/"
- if vim.fn.has("win32") == 1 then
- pattern = "[\\:]"
- end
- return pattern
-end
-
----Load the given session
----@param session string
----@param silent boolean Load the session silently?
----@return nil|string
-function M.load_session(session, silent)
- local session_data = M.make_session_data(session)
-
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedLoadPre", data = session_data })
-
- local ok, result = pcall(vim.cmd, (silent and "silent " or "") .. "source " .. e(session))
- if not ok then
- return echoerr("Error loading the session! ", result)
- end
-
- vim.g.persisted_exists = true
- vim.g.persisted_loaded_session = session
-
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedLoadPost", data = session_data })
+ end, tbl))
end
return M
diff --git a/lua/telescope/_extensions/persisted.lua b/lua/telescope/_extensions/persisted.lua
index 6ca3d9b..eedab2a 100644
--- a/lua/telescope/_extensions/persisted.lua
+++ b/lua/telescope/_extensions/persisted.lua
@@ -6,23 +6,79 @@ local action_state = require("telescope.actions.state")
local _actions = require("telescope._extensions.persisted.actions")
local _finders = require("telescope._extensions.persisted.finders")
+local persisted = require("persisted")
+local utils = require("persisted.utils")
+
+local config = persisted.config
+
local telescope_opts = {}
+---Escapes special characters before performing string substitution
+---@param str string
+---@param pattern string
+---@param replace string
+---@param n? integer
+---@return string
+---@return integer
+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 available sessions
+local function list_sessions()
+ local sep = utils.dir_pattern()
+
+ local sessions = {}
+ for _, session in pairs(persisted.list()) do
+ local session_name = escape_pattern(session, config.save_dir, "")
+ :gsub("%%", sep)
+ :gsub(vim.fn.expand("~"), sep)
+ :gsub("//", "")
+ :sub(1, -5)
+
+ if vim.fn.has("win32") == 1 then
+ session_name = escape_pattern(session_name, sep, ":", 1)
+ session_name = escape_pattern(session_name, sep, "\\")
+ end
+
+ local branch, dir_path
+
+ if string.find(session_name, "@@", 1, true) then
+ local splits = vim.split(session_name, "@@", { plain = true })
+ branch = table.remove(splits, #splits)
+ dir_path = vim.fn.join(splits, "@@")
+ else
+ dir_path = session_name
+ end
+
+ table.insert(sessions, {
+ ["name"] = session_name,
+ ["file_path"] = session,
+ ["branch"] = branch,
+ ["dir_path"] = dir_path,
+ })
+ end
+ return sessions
+end
+
+---Search through the Persisted sessions
+---@param opts table
local function search_sessions(opts)
- local config = require("persisted.config").options
opts = vim.tbl_extend("force", telescope_opts, opts or {})
pickers
.new(opts, {
prompt_title = "Sessions",
sorter = conf.generic_sorter(opts),
- finder = _finders.session_finder(require("persisted").list()),
+ finder = _finders.session_finder(list_sessions()),
attach_mappings = function(prompt_bufnr, map)
local refresh_sessions = function()
local picker = action_state.get_current_picker(prompt_bufnr)
- picker:refresh(_finders.session_finder(require("persisted").list()), {
- -- INFO: Account for users who are still using the old API
- reset_prompt = config.telescope.reset_prompt or config.telescope.reset_prompt_after_deletion,
+ picker:refresh(_finders.session_finder(list_sessions()), {
+ reset_prompt = true,
})
end
@@ -53,9 +109,9 @@ end
return require("telescope").register_extension({
setup = function(topts)
- vim.api.nvim_set_hl(0, "TelescopePersistedIsCurrent", { link = "TelescopeResultsOperator" })
- vim.api.nvim_set_hl(0, "TelescopePersistedDir", { link = "Directory" })
- vim.api.nvim_set_hl(0, "TelescopePersistedBranch", { link = "TelescopeResultsIdentifier" })
+ vim.api.nvim_set_hl(0, "PersistedTelescopeSelected", { link = "TelescopeResultsOperator", default = true })
+ vim.api.nvim_set_hl(0, "PersistedTelescopeDir", { link = "Directory", default = true })
+ vim.api.nvim_set_hl(0, "PersistedTelescopeBranch", { link = "TelescopeResultsIdentifier", default = true })
telescope_opts = topts
end,
exports = {
diff --git a/lua/telescope/_extensions/persisted/actions.lua b/lua/telescope/_extensions/persisted/actions.lua
index dff5687..f227db8 100644
--- a/lua/telescope/_extensions/persisted/actions.lua
+++ b/lua/telescope/_extensions/persisted/actions.lua
@@ -2,43 +2,43 @@ local actions_state = require("telescope.actions.state")
local transform_mod = require("telescope.actions.mt").transform_mod
local persisted = require("persisted")
+local config = persisted.config
+
local M = {}
+---Fire an event
+---@param event string
+local function fire(event)
+ vim.api.nvim_exec_autocmds("User", { pattern = "Persisted" .. event })
+end
+
---Get the selected session from Telescope
---@return table
-local get_selected_session = function()
+local function get_selected_session()
return actions_state.get_selected_entry()
end
---Load the selected session
---@param session table
----@param config table
----@return nil
-M.load_session = function(session, config)
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedTelescopeLoadPre", data = session })
-
+function M.load_session(session)
+ fire("TelescopeLoadPre")
vim.schedule(function()
persisted.load({ session = session.file_path })
end)
-
- vim.api.nvim_exec_autocmds("User", { pattern = "PersistedTelescopeLoadPost", data = session })
+ fire("TelescopeLoadPost")
end
---Delete the selected session from disk
---@return nil
-M.delete_session = function()
+function M.delete_session()
local session = get_selected_session()
- local path = session.file_path
if vim.fn.confirm("Delete [" .. session.name .. "]?", "&Yes\n&No") == 1 then
- vim.fn.delete(vim.fn.expand(path))
+ vim.fn.delete(vim.fn.expand(session.file_path))
end
end
---Change the branch of an existing session
----@param config table
----@return nil
-M.change_branch = function(config)
+function M.change_branch()
local session = get_selected_session()
local path = session.file_path
@@ -48,8 +48,7 @@ M.change_branch = function(config)
local ext = path:match("^.+(%..+)$")
-- Check for existing branch in the filename
- local branch_separator = config.branch_separator or "@@"
- local pattern = "(.*)" .. branch_separator .. ".+" .. ext .. "$"
+ local pattern = "(.*)@@.+" .. ext .. "$"
local base = path:match(pattern) or path:sub(1, #path - #ext)
-- Replace or add the new branch name
@@ -57,7 +56,7 @@ M.change_branch = function(config)
if branch == "" then
new_path = base .. ext
else
- new_path = base .. branch_separator .. branch .. ext
+ new_path = base .. "@@" .. branch .. ext
end
os.rename(path, new_path)
@@ -65,8 +64,7 @@ M.change_branch = function(config)
end
---Copy an existing session
----@return nil
-M.copy_session = function(config)
+function M.copy_session()
local session = get_selected_session()
local old_name = session.file_path:gsub(config.save_dir, "")
diff --git a/lua/telescope/_extensions/persisted/finders.lua b/lua/telescope/_extensions/persisted/finders.lua
index 8934b5d..8b1bc90 100644
--- a/lua/telescope/_extensions/persisted/finders.lua
+++ b/lua/telescope/_extensions/persisted/finders.lua
@@ -1,16 +1,18 @@
-local config = require("persisted.config")
+local config = require("persisted").config
local finders = require("telescope.finders")
local M = {}
local no_icons = {
- branch = "",
- dir = "",
selected = "",
+ dir = "",
+ branch = "",
}
-M.session_finder = function(sessions)
- local icons = vim.tbl_extend("force", no_icons, config.options.telescope.icons or {})
+---Create a finder for persisted sessions
+---@param sessions table
+function M.session_finder(sessions)
+ local icons = vim.tbl_extend("force", no_icons, config.telescope.icons or {})
local custom_displayer = function(session)
local final_str = ""
@@ -25,15 +27,15 @@ M.session_finder = function(sessions)
end
-- is current session
- append(session.file_path == vim.v.this_session and (icons.selected .. " ") or " ", "TelescopePersistedIsCurrent")
+ append(session.file_path == vim.v.this_session and (icons.selected .. " ") or " ", "PersistedTelescopeSelected")
-- session path
- append(icons.dir, "TelescopePersistedDir")
+ append(icons.dir, "PersistedTelescopeDir")
append(session.dir_path)
-- branch
if session.branch then
- append(" " .. icons.branch .. session.branch, "TelescopePersistedBranch")
+ append(" " .. icons.branch .. session.branch, "PersistedTelescopeBranch")
end
return final_str, hls
diff --git a/plugin/persisted.lua b/plugin/persisted.lua
index b743461..c00fcfe 100644
--- a/plugin/persisted.lua
+++ b/plugin/persisted.lua
@@ -2,33 +2,19 @@ if vim.g.loaded_persisted then
return
end
-local persisted = require("persisted")
-
--- Create the user commands
vim.cmd([[command! SessionStart :lua require("persisted").start()]])
vim.cmd([[command! SessionStop :lua require("persisted").stop()]])
vim.cmd([[command! SessionSave :lua require("persisted").save({ force = true })]])
vim.cmd([[command! SessionLoad :lua require("persisted").load()]])
vim.cmd([[command! SessionLoadLast :lua require("persisted").load({ last = true })]])
-vim.cmd([[command! -nargs=1 SessionLoadFromFile :lua require("persisted").load({ session = })]])
vim.cmd([[command! SessionDelete :lua require("persisted").delete()]])
vim.cmd([[command! SessionToggle :lua require("persisted").toggle()]])
--- Create the autocmds
-local group = vim.api.nvim_create_augroup("Persisted", {})
+local persisted = require("persisted")
-vim.api.nvim_create_autocmd({ "VimEnter" }, {
- group = group,
+vim.api.nvim_create_autocmd("VimEnter", {
nested = true,
callback = persisted.autoload,
})
-vim.api.nvim_create_autocmd({ "VimLeavePre" }, {
- group = group,
- nested = true,
- callback = function()
- persisted.save()
- vim.cmd('sleep 10m')
- end
-})
vim.g.loaded_persisted = true
diff --git a/tests/default_settings_spec.lua b/tests/default_settings_spec.lua
index 09c8fd1..ff1ea8d 100644
--- a/tests/default_settings_spec.lua
+++ b/tests/default_settings_spec.lua
@@ -8,7 +8,7 @@ describe("With default settings:", function()
-- vim.fn.system("rm -rf " .. e(session_dir))
end)
- it("it saves a session", function()
+ it("saves a session", function()
-- Check no file exists
assert.equals(vim.fn.system("ls tests/default_data | wc -l"):gsub("%s+", ""), "0")
@@ -24,7 +24,7 @@ describe("With default settings:", function()
assert.equals("1", vim.fn.system("ls tests/default_data | wc -l"):gsub("%s+", ""))
end)
- it("it loads a session", function()
+ it("loads a session", function()
-- Load a session
require("persisted").load()
@@ -35,19 +35,19 @@ describe("With default settings:", function()
assert.equals(vim.g.persisting, true)
end)
- it("it stops a session", function()
+ it("stops a session", function()
require("persisted").stop()
assert.equals(vim.g.persisting, false)
end)
- it("it starts a session", function()
+ it("starts a session", function()
require("persisted").start()
assert.equals(vim.g.persisting, true)
end)
- it("it lists sessions", function()
+ it("lists sessions", function()
local sessions = require("persisted").list()
local path = require("plenary.path"):new(sessions[1].file_path)
@@ -59,19 +59,10 @@ local async = require("plenary.async.tests")
local util = require("plenary.async.util")
async.describe("With default settings:", function()
- async.it("it deletes a session", function()
+ async.it("deletes a session", function()
require("persisted").delete()
util.scheduler()
assert.equals("0", vim.fn.system("ls tests/default_data | wc -l"):gsub("%s+", ""))
end)
end)
-
-describe("Utilities", function()
- it("can make derive the session name", function()
- local session = "%home%username%projects%front@@user%fix-analytics-export-null-values.vim"
- local data = require("persisted.utils").make_session_data(session)
-
- assert.equals("home/username/projects/front@@user/fix-analytics-export-null-values", data.name)
- end)
-end)
diff --git a/tests/follow_cwd/follow_cwd_spec.lua b/tests/follow_cwd/follow_cwd_spec.lua
index 1124a73..f5d1a7b 100644
--- a/tests/follow_cwd/follow_cwd_spec.lua
+++ b/tests/follow_cwd/follow_cwd_spec.lua
@@ -1,15 +1,13 @@
-pcall(vim.fn.system, "rm -rf tests/dummy_data")
-
local session_dir = vim.fn.getcwd() .. "/tests/dummy_data/"
--- follow_cwd = true
+pcall(vim.fn.system, "rm -rf tests/dummy_data")
require("persisted").setup({
save_dir = session_dir,
follow_cwd = true,
})
-describe("Follow cwd change", function()
- it("creates two sessions with change in cwd", function()
+describe("Follow cwd", function()
+ it("creates two sessions", function()
vim.cmd(":e tests/stubs/test_autoload.txt")
vim.cmd(":w")
@@ -19,15 +17,15 @@ describe("Follow cwd change", function()
require("persisted").save()
vim.cmd(":bdelete")
end)
+
it("ensures both sessions were created", function()
require("persisted").load()
local pattern = "/"
- local branch1 = require("persisted").get_branch()
- local name1 = vim.fn.getcwd():gsub(pattern, "%%") .. (branch1 or "") .. ".vim"
+ local name1 = vim.fn.getcwd():gsub(pattern, "%%") .. ".vim"
+
vim.cmd(":cd ../..")
- local branch2 = require("persisted").get_branch()
- local name2 = vim.fn.getcwd():gsub(pattern, "%%") .. (branch2 or "") .. ".vim"
+ local name2 = vim.fn.getcwd():gsub(pattern, "%%") .. ".vim"
local sessions = vim.fn.readdir(session_dir)
assert.equals(sessions[1], name1)
@@ -35,14 +33,13 @@ describe("Follow cwd change", function()
end)
end)
--- follow_cwd = false
pcall(vim.fn.system, "rm -rf tests/dummy_data")
require("persisted").setup({
save_dir = session_dir,
follow_cwd = false,
})
-describe("Don't follow cwd change", function()
+describe("Follow a cwd change", function()
it("creates two sessions with change in cwd", function()
vim.cmd(":e tests/stubs/test_autoload.txt")
vim.cmd(":w")
@@ -56,11 +53,11 @@ describe("Don't follow cwd change", function()
it("ensures only one session was created", function()
local pattern = "/"
vim.cmd(":cd ../..")
- local branch = require("persisted").get_branch()
- local name = vim.fn.getcwd():gsub(pattern, "%%") .. (branch or "") .. ".vim"
+
+ local name = vim.fn.getcwd():gsub(pattern, "%%") .. ".vim"
local sessions = vim.fn.readdir(session_dir)
assert.equals(#sessions, 1)
- assert.equals(name, sessions[1])
+ assert.equals(sessions[1], name)
end)
end)
diff --git a/tests/git_branching/git_branching_spec.lua b/tests/git_branching/git_branching_spec.lua
index 87e9ad5..1a78dff 100644
--- a/tests/git_branching/git_branching_spec.lua
+++ b/tests/git_branching/git_branching_spec.lua
@@ -21,9 +21,24 @@ describe("Git Branching", function()
end)
it("ensures the session has the branch name in", function()
+ if vim.fn.isdirectory(session_dir .. "/.git") == 0 then
+ vim.fn.system("mkdir -p " .. session_dir)
+ vim.fn.system("cd " .. session_dir .. " && git init")
+ end
+
+ local branch_name = require("persisted").branch()
+
+ -- Check if branch_name is valid
+ if not branch_name then
+ print("Failed to get branch name.")
+ branch_name = ""
+ else
+ branch_name = "@@" .. branch_name
+ end
+
-- Workout what the name should be
local pattern = "/"
- local name = vim.fn.getcwd():gsub(pattern, "%%") .. require("persisted").get_branch() .. ".vim"
+ local name = vim.fn.getcwd():gsub(pattern, "%%") .. branch_name .. ".vim"
local session = vim.fn.glob(session_dir .. "*.vim", true, true)[1]
session:gsub(session_dir .. "/", "")