Skip to content

Commit

Permalink
feat!: this commit breaks compatibility between branches `merge-sessi…
Browse files Browse the repository at this point in the history
…on-lens`

and `main`.

- Rename the commands so they are now prefixed with `Session`. i.e
`SaveSession` is now `SessionSave`. This closes #175.
- Add a `session_lens` config option to the main `require("auto-session").setup(config)` config.
- Add feature to toggle between two sessions through session-lens.

The plan is for this branch merge to be tagged as `v2` while
the current work in main is tagged as `v1`. Either that or keeping the
current `main` branch as effectively `v1` and renaming this branch to
`v2`, final decision on this is still up in the air.
  • Loading branch information
rmagatti committed Apr 10, 2023
1 parent 63984ed commit a2cc591
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 455 deletions.
46 changes: 28 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ Auto Session takes advantage of Neovim's existing session management capabilitie

1. When starting `nvim` with no arguments, auto-session will try to restore an existing session for the current `cwd` if one exists.
2. When starting `nvim .` with some argument, auto-session will do nothing.
3. Even after starting `nvim` with an argument, a session can still be manually restored by running `:RestoreSession`.
3. Even after starting `nvim` with an argument, a session can still be manually restored by running `:SessionRestore`.
4. Any session saving and restoration takes into consideration the current working directory `cwd`.
5. When piping to `nvim`, e.g: `cat myfile | nvim`, auto-session behaves like #2.

:warning: Please note that if there are errors in your config, restoring the session might fail, if that happens, auto session will then disable auto saving for the current session.
Manually saving a session can still be done by calling `:SaveSession`.
Manually saving a session can still be done by calling `:SessionSave`.

AutoSession now tracks `cwd` changes!
By default, handling is as follows:
Expand Down Expand Up @@ -164,7 +164,7 @@ set sessionoptions+=winpos,terminal,folds
### Last Session

This optional feature enables the keeping track and loading of the last session.
This loading of a last session happens only when a `RestoreSession` could not find a session for the current dir.
This loading of a last session happens only when a `SessionRestore` could not find a session for the current dir.
This feature can come in handy when starting Neovim from a GUI for example.
:warning: This feature is still experimental and as of right now it interferes with the plugin's ability to auto create new sessions when opening Neovim in a new directory.

Expand All @@ -181,13 +181,13 @@ require('auto-session').setup {
Auto Session exposes two commands that can be used or mapped to any keybindings for manually saving and restoring sessions.

```viml
:SaveSession " saves or creates a session in the currently set `auto_session_root_dir`.
:SaveSession ~/my/custom/path " saves or creates a session in the specified directory path.
:RestoreSession " restores a previously saved session based on the `cwd`.
:RestoreSession ~/my/custom/path " restores a previously saved session based on the provided path.
:RestoreSessionFromFile ~/session/path " restores any currently saved session
:DeleteSession " deletes a session in the currently set `auto_session_root_dir`.
:DeleteSession ~/my/custom/path " deleetes a session based on the provided path.
:SessionSave " saves or creates a session in the currently set `auto_session_root_dir`.
:SessionSave ~/my/custom/path " saves or creates a session in the specified directory path.
:SessionRestore " restores a previously saved session based on the `cwd`.
:SessionRestore ~/my/custom/path " restores a previously saved session based on the provided path.
:SessionRestoreFromFile ~/session/path " restores any currently saved session
:SessionDelete " deletes a session in the currently set `auto_session_root_dir`.
:SessionDelete ~/my/custom/path " deleetes a session based on the provided path.
:Autosession search
:Autosession delete
```
Expand Down Expand Up @@ -276,20 +276,30 @@ Session Lens has been merged into Auto Session! This means all the functionality
You still need to call the session-lens specific setup function for things to work properly since even though these plugins are now merged, they are effectily fully modular and auto-session does not depend on session-lens functionality.

```lua
require("session-lens").setup {
path_display = { "shorten" },
theme_conf = { border = true },
previewer = false,
require("auto-session").setup {
log_level = vim.log.levels.ERROR,
auto_session_suppress_dirs = { "~/", "~/Projects", "~/Downloads", "/" },
auto_session_use_git_branch = false,

auto_session_enable_last_session = false,

session_lens = {
theme_conf = { border = true },
previewer = false,
},
}

-- Mapping to search sessions using the session-lens search_session function
vim.keymap.set("n", "<C-s>", require("session-lens").search_session, {
-- Set mapping for searching a session.
vim.keymap.set("n", "<C-s>", require("auto-session.session-lens").search_session, {
noremap = true,
})
```
Auto Session provides its own `:Autosession search` and `:Autosession delete` commands, but session-lens is a more complete version of those commands that is specificly built to be used with `telescope.nvim`. These commands make use of `vim.ui.select` which can itself be implemented by other plugins other than telescope.

Sometime after `telescope.nvim` has been started, you'll want to call `require("telescope").load_extension "session-lens"` so that auto completion can happen for the `:Telescope session-lens` commands.
*Note:* hitting `<C-s>` on an open session-lens picker will automatically try to restore the previous session opened. This can give you a nice flow if you're constantly switching between two projects.

Sometime after `telescope.nvim` has been started, you'll want to call ```lua require("telescope").load_extension "session-lens"```` so that command completion works for `:Telescope session-lens` commands.

Auto Session provides its own `:Autosession search` and `:Autosession delete` commands, but session-lens is a more complete version of those commands that is specificly built to be used with `telescope.nvim`. These commands make use of `vim.ui.select` which can itself be implemented by other plugins other than telescope.

### Preview

Expand Down
111 changes: 100 additions & 11 deletions lua/auto-session.lua → lua/auto-session/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local Lib = require "auto-session.lib"
local autocmds = require "auto-session.autocmds"
local AutoCmds = require "auto-session.autocmds"
local SessionLens = require "auto-session.session-lens"

----------- Setup ----------
local AutoSession = {
Expand Down Expand Up @@ -34,7 +35,7 @@ end

---table default config for auto session
---@class defaultConf
---@field log_level string debug, info, error
---@field log_level string|integer "debug", "info", "warn", "error" or vim.log.levels.DEBUG, vim.log.levels.INFO, vim.log.levels.WARN, vim.log.levels.ERROR
---@field auto_session_enable_last_session boolean
---@field auto_session_last_session_dir string
---@field auto_session_root_dir string root directory for session files, by default is `vim.fn.stdpath('data')/sessions/`
Expand Down Expand Up @@ -87,10 +88,12 @@ local luaOnlyConf = {
---@field control_dir string
---@field control_filename string

---@type session_control
session_control = {
control_dir = vim.fn.stdpath "data" .. "/auto_session/", -- Auto session control dir, for control files, like alternating between two sessions with session-lens
control_filename = "session_control.json", -- File name of the session control file
---@type session_lens_config
session_lens = {
session_control = {
control_dir = vim.fn.stdpath "data" .. "/auto_session/", -- Auto session control dir, for control files, like alternating between two sessions with session-lens
control_filename = "session_control.json", -- File name of the session control file
},
},
}

Expand All @@ -108,8 +111,10 @@ function AutoSession.setup(config)
AutoSession.conf = vim.tbl_deep_extend("force", AutoSession.conf, config or {})
Lib.ROOT_DIR = AutoSession.conf.auto_session_root_dir
Lib.setup(AutoSession.conf)
SessionLens.setup(AutoSession.conf, AutoSession)
AutoCmds.setup_autocmds(AutoSession.conf, AutoSession)

autocmds.setup_autocmds(AutoSession.conf, AutoSession)
SetupAutocmds()
end

local function is_enabled()
Expand Down Expand Up @@ -502,8 +507,8 @@ vim.api.nvim_create_user_command("Autosession", handle_autosession_command, { na
-- end

local function write_to_session_control_json(session_file_name)
local control_dir = AutoSession.conf.session_control.control_dir
local control_file = AutoSession.conf.session_control.control_filename
local control_dir = AutoSession.conf.session_lens.session_control.control_dir
local control_file = AutoSession.conf.session_lens.session_control.control_filename
session_file_name = Lib.expand(session_file_name)

Lib.init_dir(control_dir)
Expand All @@ -512,7 +517,7 @@ local function write_to_session_control_json(session_file_name)

local log_ending_state = function()
local content = vim.fn.readfile(session_control_file)
local session_control = vim.json.decode(content[1] or "{}")
local session_control = vim.json.decode(content[1] or "{}") or {}
local sessions = { current = session_control.current, alternate = session_control.alternate }

Lib.logger.debug("session control file contents", { sessions = sessions, content = content })
Expand All @@ -521,7 +526,7 @@ local function write_to_session_control_json(session_file_name)
if vim.fn.filereadable(session_control_file) == 1 then
local content = vim.fn.readfile(session_control_file)
Lib.logger.debug { content = content }
local json = vim.json.decode(content[1] or "{}")
local json = vim.json.decode(content[1] or "{}") or {}

local sessions = {
current = session_file_name,
Expand Down Expand Up @@ -809,4 +814,88 @@ function AutoSession.DeleteSession(...)
run_hook_cmds(post_cmds, "post-delete")
end

function SetupAutocmds()
Lib.logger.info "Setting up autocmds"

-- Check if the auto-session plugin has already been loaded to prevent loading it twice
if vim.g.loaded_auto_session ~= nil then
return
end

-- Initialize variables
vim.g.in_pager_mode = false

local function SaveSession(args)
return AutoSession.SaveSession(args.args, false)
end

local function SessionRestore(args)
return AutoSession.RestoreSession(args.args)
end

local function SessionDelete(args)
return AutoSession.DeleteSession(args.args)
end

local function DisableAutoSave()
return AutoSession.DisableAutoSave()
end

vim.api.nvim_create_user_command(
"SessionSave",
SaveSession,
{ bang = true, desc = "Save the current session. Based in cwd if no arguments are passed" }
)

vim.api.nvim_create_user_command("SessionRestore", SessionRestore, { bang = true, desc = "Restore Session" })

vim.api.nvim_create_user_command("DisableAutoSave", DisableAutoSave, { bang = true, desc = "Disable Auto Save" })

vim.api.nvim_create_user_command(
"SessionRestoreFromFile",
DisableAutoSave,
{ complete = AutoSession.CompleteSessions, bang = true, nargs = "*", desc = "Restore Session from file" }
)

vim.api.nvim_create_user_command(
"SessionDelete",
SessionDelete,
{ complete = AutoSession.CompleteSessions, bang = true, nargs = "*", desc = "Delete Session" }
)

local group = vim.api.nvim_create_augroup("auto_session_group", {})

vim.api.nvim_create_autocmd({ "StdinReadPre" }, {
group = group,
pattern = "*",
callback = function()
vim.g.in_pager_mode = true
end,
})

vim.api.nvim_create_autocmd({ "VimEnter" }, {
group = group,
pattern = "*",
nested = true,
callback = function()
if not vim.g.in_pager_mode then
AutoSession.AutoRestoreSession()
end
end,
})

vim.api.nvim_create_autocmd({ "VimLeave" }, {
group = group,
pattern = "*",
callback = function()
if not vim.g.in_pager_mode then
AutoSession.AutoSaveSession()
end
end,
})

-- Set a flag to indicate that the plugin has been loaded
vim.g.loaded_auto_session = true
end

return AutoSession
32 changes: 19 additions & 13 deletions lua/auto-session/session-lens/actions.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
local AutoSession = require "auto-session"
local action_state = require "telescope.actions.state"
local actions = require "telescope.actions"
local Lib = require "auto-session.lib"

local SessionLensActions = {}
local M = {
conf = {},
functions = {},
}

function M.setup(config, functions)
M.conf = vim.tbl_deep_extend("force", config, M.conf)
M.functions = functions
end

-- TODO: Either use this or actually store the latest sessions on load time, then just alternate between them here.
-- local function get_second_to_latest_session_by_last_edited()
Expand Down Expand Up @@ -71,12 +78,11 @@ local SessionLensActions = {}
-- end

local function get_alternate_session()
local filepath = AutoSession.conf.session_control.control_dir .. AutoSession.conf.session_control.control_filename
local filepath = M.conf.session_control.control_dir .. M.conf.session_control.control_filename

if vim.fn.filereadable(filepath) == 1 then
local content = vim.fn.readfile(filepath)[1] or "{}"

local json = vim.json.decode(content)
local json = vim.json.decode(content) or {} -- should never hit the or clause since we're defaulting to a string for content

local sessions = {
current = json.current,
Expand Down Expand Up @@ -107,36 +113,36 @@ local function source_session(selection, prompt_bufnr)
then
-- Take advatage of cwd_change_handling behaviour for switching sessions
Lib.logger.debug "Triggering vim.fn.chdir since cwd_change_handling feature is enabled"
vim.fn.chdir(AutoSession.format_file_name(type(selection) == "table" and selection.filename or selection))
vim.fn.chdir(M.functions.format_file_name(type(selection) == "table" and selection.filename or selection))
else
Lib.logger.debug "Triggering session-lens behaviour since cwd_change_handling feature is disabled"
AutoSession.AutoSaveSession()
M.functions.AutoSaveSession()
vim.cmd "%bd!"
vim.cmd "clearjumps"
AutoSession.RestoreSession(type(selection) == "table" and selection.path or selection)
M.functions.RestoreSession(type(selection) == "table" and selection.path or selection)
end
end, 50)
end

---Source session action
---Source a selected session after doing proper current session saving and cleanup
---@param prompt_bufnr number the telescope prompt bufnr
SessionLensActions.source_session = function(prompt_bufnr)
M.source_session = function(prompt_bufnr)
local selection = action_state.get_selected_entry()
source_session(selection, prompt_bufnr)
end

---Delete session action
---Delete a selected session file
---@param prompt_bufnr number the telescope prompt bufnr
SessionLensActions.delete_session = function(prompt_bufnr)
M.delete_session = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:delete_selection(function(selection)
AutoSession.DeleteSession(selection.path)
M.functions.DeleteSession(selection.path)
end)
end

SessionLensActions.alternate_session = function(prompt_bufnr)
M.alternate_session = function(prompt_bufnr)
local alternate_session = get_alternate_session()

if not alternate_session then
Expand All @@ -158,4 +164,4 @@ end
---"/Users/ronnieandrewmagatti/.local/share/nvim/sessions/%Users%ronnieandrewmagatti%Projects%auto-session.vim"
---"/Users/ronnieandrewmagatti/.local/share/nvim/sessions/\\%Users\\%ronnieandrewmagatti\\%Projects\\%auto-session.vim"

return SessionLensActions
return M
Loading

0 comments on commit a2cc591

Please sign in to comment.