Skip to content

Commit

Permalink
feat: copy session from telescope picker
Browse files Browse the repository at this point in the history
  • Loading branch information
cameronr committed Sep 23, 2024
1 parent 0caedb8 commit 30e14d9
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 27 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Here are the default settings:
-- Mode can be a string or a table, e.g. {"i", "n"} for both insert and normal mode
delete_session = { "i", "<C-D>" },
alternate_session = { "i", "<C-S>" },
copy_session = { "i", "<C-Y>" },
},

session_control = {
Expand Down
2 changes: 2 additions & 0 deletions lua/auto-session/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ local M = {}
---@class SessionLensMappings
---@field delete_session table mode and key for deleting a session from the picker
---@field alternate_session table mode and key for swapping to alertnate session from the picker
---@field copy_session table mode and key for copying a session from the picker

---@type AutoSession.Config
local defaults = {
Expand Down Expand Up @@ -94,6 +95,7 @@ local defaults = {
-- Mode can be a string or a table, e.g. {"i", "n"} for both insert and normal mode
delete_session = { "i", "<C-D>" },
alternate_session = { "i", "<C-S>" },
copy_session = { "i", "<C-Y>" },
},

---@type SessionControl
Expand Down
2 changes: 1 addition & 1 deletion lua/auto-session/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ end
---@private
---Gets the root directory of where to save the sessions.
---By default this resolves to `vim.fn.stdpath "data" .. "/sessions/"`
---@param with_trailing_separator? boolean whether to incude the trailing separator. A few places (telescope picker don't expect a trailing separator) (Defaults to true)
---@param with_trailing_separator? boolean whether to incude the trailing separator. A few places (e.g. telescope picker) don't expect a trailing separator (Defaults to true)
---@return string
function AutoSession.get_root_dir(with_trailing_separator)
if with_trailing_separator == nil then
Expand Down
15 changes: 14 additions & 1 deletion lua/auto-session/session-lens/actions.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local AutoSession = require "auto-session"
local Config = require "auto-session.config"
local Lib = require "auto-session.lib"
local transform_mod = require("telescope.actions.mt").transform_mod

local M = {}

Expand Down Expand Up @@ -92,4 +93,16 @@ M.alternate_session = function(prompt_bufnr)
source_session(session_name, prompt_bufnr)
end

return M
---@private
---Copy session action
---Ask user for the new name and then copy the session to that name
M.copy_session = function(_)
local action_state = require "telescope.actions.state"
local selection = action_state.get_selected_entry()

local new_name = vim.fn.input("New session name: ", selection.display)
local content = vim.fn.readfile(selection.path)
vim.fn.writefile(content, AutoSession.get_root_dir() .. Lib.escape_session_name(new_name) .. ".vim")
end

return transform_mod(M)
57 changes: 32 additions & 25 deletions lua/auto-session/session-lens/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ end
---Triggers the customized telescope picker for switching sessions
---@param custom_opts any
SessionLens.search_session = function(custom_opts)
local themes = require "telescope.themes"
local telescope_themes = require "telescope.themes"
local telescope_actions = require "telescope.actions"
local telescope_finders = require "telescope.finders"
local telescope_conf = require("telescope.config").values

custom_opts = (vim.tbl_isempty(custom_opts or {}) or custom_opts == nil) and Config.session_lens or custom_opts

Expand All @@ -88,7 +90,7 @@ SessionLens.search_session = function(custom_opts)
custom_opts.shorten_path = nil
end

local theme_opts = themes.get_dropdown(custom_opts.theme_conf)
local theme_opts = telescope_themes.get_dropdown(custom_opts.theme_conf)

-- Use default previewer config by setting the value to nil if some sets previewer to true in the custom config.
-- Passing in the boolean value errors out in the telescope code with the picker trying to index a boolean instead of a table.
Expand All @@ -97,45 +99,50 @@ SessionLens.search_session = function(custom_opts)
custom_opts["previewer"] = nil
end

local opts = {
prompt_title = "Sessions",
local finder_opts = {
entry_maker = SessionLens.make_telescope_callback(custom_opts),
cwd = session_root_dir,
attach_mappings = function(_, map)
}

local find_command
if 1 == vim.fn.executable "rg" then
find_command = { "rg", "--files", "--color", "never", "--sortr", "modified" }
elseif 1 == vim.fn.executable "ls" then
find_command = { "ls", "-t" }
elseif 1 == vim.fn.executable "cmd" and vim.fn.has "win32" == 1 then
find_command = { "cmd", "/C", "dir", "/b", "/o-d" }
end

local opts = {
prompt_title = "Sessions",
attach_mappings = function(prompt_bufnr, map)
telescope_actions.select_default:replace(Actions.source_session)

local mappings = Config.session_lens.mappings
if mappings then
map(mappings.delete_session[1], mappings.delete_session[2], Actions.delete_session)
map(mappings.alternate_session[1], mappings.alternate_session[2], Actions.alternate_session)

Actions.copy_session:enhance {
post = function()
local action_state = require "telescope.actions.state"
local picker = action_state.get_current_picker(prompt_bufnr)
picker:refresh(telescope_finders.new_oneshot_job(find_command, finder_opts), { reset_prompt = true })
end,
}

map(mappings.copy_session[1], mappings.copy_session[2], Actions.copy_session)
end
return true
end,
}
opts = vim.tbl_deep_extend("force", opts, theme_opts, custom_opts or {})

local find_command = (function()
if opts.find_command then
if type(opts.find_command) == "function" then
return opts.find_command(opts)
end
return opts.find_command
elseif 1 == vim.fn.executable "rg" then
return { "rg", "--files", "--color", "never", "--sortr", "modified" }
elseif 1 == vim.fn.executable "ls" then
return { "ls", "-t" }
elseif 1 == vim.fn.executable "cmd" and vim.fn.has "win32" == 1 then
return { "cmd", "/C", "dir", "/b", "/o-d" }
end
end)()

local finders = require "telescope.finders"
local conf = require("telescope.config").values
require("telescope.pickers")
.new(opts, {
finder = finders.new_oneshot_job(find_command, opts),
previewer = conf.grep_previewer(opts),
sorter = conf.file_sorter(opts),
finder = telescope_finders.new_oneshot_job(find_command, finder_opts),
previewer = telescope_conf.file_previewer(opts),
sorter = telescope_conf.file_sorter(opts),
})
:find()
end
Expand Down
19 changes: 19 additions & 0 deletions tests/mini-tests/test_ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ T["session lens"]["can load a session"] = function()
expect.equality(1, child.fn.bufexists(TL.other_file))
end

T["session lens"]["can copy a session"] = function()
expect.equality(0, child.fn.bufexists(TL.test_file))
child.cmd "SessionSearch"
-- give the UI time to come up
local session_name = "project_x"
vim.loop.sleep(250)
child.type_keys(session_name)
vim.loop.sleep(20)
child.type_keys "<C-Y>"
vim.loop.sleep(20)

-- will append to session_name
local copy_name = "copy"
child.type_keys(copy_name .. "<cr>")
-- give the session time to load
vim.loop.sleep(500)
expect.equality(1, vim.fn.filereadable(TL.makeSessionPath(session_name .. copy_name)))
end

T["session lens"]["can delete a session"] = function()
expect.equality(1, vim.fn.filereadable(TL.named_session_path))
child.cmd "SessionSearch"
Expand Down

0 comments on commit 30e14d9

Please sign in to comment.