Skip to content

Commit 16016db

Browse files
authored
Merge pull request #400 from cameronr/main
feat: support for custom Snacks picker
2 parents 021b64e + cc4ab06 commit 16016db

File tree

5 files changed

+121
-46
lines changed

5 files changed

+121
-46
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ AutoSession exposes the following commands that can be used or mapped to any key
141141
142142
:SessionPurgeOrphaned " removes all orphaned sessions with no working directory left.
143143
144-
:SessionSearch " open a session picker, uses Telescope if installed, vim.ui.select otherwise
144+
:SessionSearch " open a session picker, uses Telescope or Snacks if installed, vim.ui.select otherwise
145145
146146
:Autosession search " open a vim.ui.select picker to choose a session to load.
147147
:Autosession delete " open a vim.ui.select picker to choose a session to delete.
@@ -153,7 +153,7 @@ If you create a manually named session via `SessionSave my_session` or you resto
153153

154154
## 🔭 Session Lens
155155

156-
You can use Telescope to see, load, and delete your sessions. It's enabled by default if you have Telescope, but here's the Lazy config that shows the configuration options:
156+
You can use Telescope or [snacks.nvim](https://github.com/folke/snacks.nvim) to see, load, and delete your sessions. It's enabled by default if you have Telescope, but here's the Lazy config that shows the configuration options:
157157

158158
```lua
159159

@@ -198,7 +198,7 @@ You can use Telescope to see, load, and delete your sessions. It's enabled by de
198198
```
199199

200200
You can use `:SessionSearch` to launch the session picker. If `load_on_setup = false`, `:SessionSearch` will initialize the Telescope extension when called. You can also use
201-
`:Telescope session-lens` to launch the session picker but only if `load_on_setup = true` or you've previously called `SessionSearch`.
201+
`:Telescope session-lens` to launch the session picker but only if `load_on_setup = true` or you've previously called `SessionSearch`. If you don't have Telescope installed but do have Snacks installed (and the picker enabled), AutoSession will use Snacks as the session picker. No change in configuration is needed (e.g. it will use the same keymap config).
202202

203203
The following default keymaps are available when the session-lens picker is open:
204204

doc/auto-session.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ This plugin provides the following commands:
9595

9696
`:SessionPurgeOrphaned` - removes all orphaned sessions with no working directory left.
9797

98-
`:SessionSearch` - open a session picker, uses Telescope if installed, vim.ui.select otherwise
98+
`:SessionSearch` - open a session picker, uses Telescope or Snacks if installed, vim.ui.select otherwise
9999

100100
==============================================================================
101101
API *auto-session.api*

lua/auto-session/autocmds.lua

+80-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ local SessionLens -- will be initialized later
2121
---
2222
--- `:SessionPurgeOrphaned` - removes all orphaned sessions with no working directory left.
2323
---
24-
--- `:SessionSearch` - open a session picker, uses Telescope if installed, vim.ui.select otherwise
24+
--- `:SessionSearch` - open a session picker, uses Telescope or Snacks if installed, vim.ui.select otherwise
2525
---@brief ]]
2626

2727
local M = {}
@@ -122,6 +122,79 @@ local function setup_session_lens()
122122
return true
123123
end
124124

125+
local function has_snacks()
126+
local success, snacks_picker_enabled = pcall(function()
127+
---@diagnostic disable-next-line: undefined-field
128+
return Snacks.config.picker.enabled
129+
end)
130+
return success and snacks_picker_enabled
131+
end
132+
133+
local function snacks_session_search()
134+
local mappings = Config.session_lens.mappings or {}
135+
Snacks.picker.pick {
136+
title = "Sessions",
137+
finder = function()
138+
return Lib.get_session_list(M.AutoSession.get_root_dir())
139+
end,
140+
format = "text",
141+
transform = function(item)
142+
item.text = item.display_name
143+
end,
144+
layout = {
145+
preview = Config.session_lens.theme_conf.preview,
146+
},
147+
win = {
148+
input = {
149+
keys = {
150+
["dd"] = "session_delete",
151+
[mappings.delete_session[2]] = { "session_delete", mode = mappings.delete_session[1] },
152+
[mappings.alternate_session[2]] = { "session_alternate", mode = mappings.alternate_session[1] },
153+
[mappings.copy_session[2]] = { "session_copy", mode = mappings.copy_session[1] },
154+
},
155+
},
156+
list = { keys = { ["dd"] = "session_delete" } },
157+
},
158+
actions = {
159+
confirm = function(picker, item)
160+
picker:close()
161+
vim.schedule(function()
162+
M.AutoSession.autosave_and_restore(item.session_name)
163+
end)
164+
end,
165+
session_delete = function(picker, item)
166+
vim.schedule(function()
167+
M.AutoSession.DeleteSessionFile(item.path, item.display_name)
168+
picker:find() -- refresh picker
169+
end)
170+
end,
171+
session_alternate = function(picker, _)
172+
vim.schedule(function()
173+
local altername_session_name = Lib.get_alternate_session_name(Config.session_lens.session_control)
174+
if not altername_session_name then
175+
return
176+
end
177+
picker:close()
178+
vim.defer_fn(function()
179+
M.AutoSession.autosave_and_restore(altername_session_name)
180+
end, 50)
181+
end)
182+
end,
183+
session_copy = function(picker, item)
184+
vim.schedule(function()
185+
local new_name = vim.fn.input("New session name: ", item.text)
186+
if not new_name or new_name == "" or new_name == item.text then
187+
return
188+
end
189+
local content = vim.fn.readfile(item.path)
190+
vim.fn.writefile(content, M.AutoSession.get_root_dir() .. Lib.escape_session_name(new_name) .. ".vim")
191+
picker:find() -- refresh picker
192+
end)
193+
end,
194+
},
195+
}
196+
end
197+
125198
local function setup_dirchanged_autocmds(AutoSession)
126199
if not Config.cwd_change_handling then
127200
Lib.logger.debug "cwd_change_handling is disabled, skipping setting DirChangedPre and DirChanged autocmd handling"
@@ -256,12 +329,17 @@ function M.setup_autocmds(AutoSession)
256329
})
257330

258331
vim.api.nvim_create_user_command("SessionSearch", function()
259-
-- If Telescope is installed, use that otherwise use vim.ui.select
332+
-- Use telescope if installed, otherwise snacks, otherwise vim.ui.select
260333
if setup_session_lens() and SessionLens then
261334
vim.cmd "Telescope session-lens"
262335
return
263336
end
264337

338+
if has_snacks() then
339+
snacks_session_search()
340+
return
341+
end
342+
265343
handle_autosession_command { args = "search" }
266344
end, {
267345
desc = "Open a session picker",

lua/auto-session/lib.lua

+34
Original file line numberDiff line numberDiff line change
@@ -681,4 +681,38 @@ function Lib.get_session_list(sessions_dir)
681681
end, entries)
682682
end
683683

684+
---Get the name of the altnernate session stored in the session control file
685+
---@return string|nil name of the alternate session, suitable for calls to LoadSession
686+
function Lib.get_alternate_session_name(session_control_conf)
687+
if not session_control_conf then
688+
Lib.logger.error "No session_control in config!"
689+
return nil
690+
end
691+
692+
local filepath = vim.fn.expand(session_control_conf.control_dir) .. session_control_conf.control_filename
693+
694+
if vim.fn.filereadable(filepath) == 0 then
695+
return nil
696+
end
697+
698+
local json = Lib.load_session_control_file(filepath)
699+
700+
local sessions = {
701+
current = json.current,
702+
alternate = json.alternate,
703+
}
704+
705+
Lib.logger.debug("get_alternate_session_name", { sessions = sessions, json = json })
706+
707+
if sessions.current == sessions.alternate then
708+
Lib.logger.info "Current session is the same as alternate, returning nil"
709+
return nil
710+
end
711+
local file_name = vim.fn.fnamemodify(sessions.alternate, ":t")
712+
if Lib.is_legacy_file_name(file_name) then
713+
return (Lib.legacy_unescape_session_name(file_name):gsub("%.vim$", ""))
714+
end
715+
return Lib.escaped_session_name_to_session_name(file_name)
716+
end
717+
684718
return Lib

lua/auto-session/session-lens/actions.lua

+3-40
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,6 @@ local transform_mod = require("telescope.actions.mt").transform_mod
66
local M = {}
77

88
---@private
9-
local function get_alternate_session()
10-
---@diagnostic disable-next-line: undefined-field
11-
local session_control_conf = Config.session_lens.session_control
12-
13-
if not session_control_conf then
14-
Lib.logger.error "No session_control in config!"
15-
return
16-
end
17-
18-
local filepath = vim.fn.expand(session_control_conf.control_dir) .. session_control_conf.control_filename
19-
20-
if vim.fn.filereadable(filepath) == 1 then
21-
local json = Lib.load_session_control_file(filepath)
22-
23-
local sessions = {
24-
current = json.current,
25-
alternate = json.alternate,
26-
}
27-
28-
Lib.logger.debug("get_alternate_session", { sessions = sessions, json = json })
29-
30-
if sessions.current ~= sessions.alternate then
31-
return sessions.alternate
32-
end
33-
34-
Lib.logger.info "Current session is the same as alternate!"
35-
end
36-
end
379

3810
local function source_session(session_name, prompt_bufnr)
3911
if prompt_bufnr then
@@ -74,23 +46,14 @@ end
7446

7547
---@private
7648
M.alternate_session = function(prompt_bufnr)
77-
local alternate_session = get_alternate_session()
78-
79-
if not alternate_session then
49+
local alternate_session_name = Lib.get_alternate_session_name(Config.session_lens.session_control)
50+
if not alternate_session_name then
8051
vim.notify "There is no alternate session"
8152
-- Keep the picker open in case they want to select a session to load
8253
return
8354
end
8455

85-
local file_name = vim.fn.fnamemodify(alternate_session, ":t")
86-
local session_name
87-
if Lib.is_legacy_file_name(file_name) then
88-
session_name = (Lib.legacy_unescape_session_name(file_name):gsub("%.vim$", ""))
89-
else
90-
session_name = Lib.escaped_session_name_to_session_name(file_name)
91-
end
92-
93-
source_session(session_name, prompt_bufnr)
56+
source_session(alternate_session_name, prompt_bufnr)
9457
end
9558

9659
---@private

0 commit comments

Comments
 (0)