Skip to content

Commit

Permalink
Merge pull request #382 from cameronr/telescope-refactor
Browse files Browse the repository at this point in the history
feat: copy session from telescope picker
  • Loading branch information
cameronr authored Sep 24, 2024
2 parents 0caedb8 + 49a4e68 commit 21e3385
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 164 deletions.
3 changes: 3 additions & 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 Expand Up @@ -176,8 +177,10 @@ You can use Telescope to see, load, and delete your sessions. It's enabled by de
-- 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>" },
},
-- Can also set some Telescope picker options
-- For all options, see: https://github.com/nvim-telescope/telescope.nvim/blob/master/doc/telescope.txt#L112
theme_conf = {
border = true,
-- layout_config = {
Expand Down
1 change: 1 addition & 0 deletions doc/auto-session.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ SessionLensMappings *SessionLensMappings*
Fields: ~
{delete_session} (table) mode and key for deleting a session from the picker
{alternate_session} (table) mode and key for swapping to alertnate session from the picker
{copy_session} (table) mode and key for copying a session from the picker


==============================================================================
Expand Down
42 changes: 6 additions & 36 deletions lua/auto-session/autocmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,6 @@ end
---@field display_name string
---@field path string

---@return PickerItem[]
local function get_session_files()
local files = {}
local sessions_dir = M.AutoSession.get_root_dir()

if vim.fn.isdirectory(sessions_dir) == Lib._VIM_FALSE then
return files
end

local entries = vim.fn.readdir(sessions_dir, function(item)
return Lib.is_session_file(sessions_dir .. item)
end)

return vim.tbl_map(function(file_name)
-- sessions_dir is guaranteed to have a trailing separator so don't need to add another one here
local session_name
local display_name
if Lib.is_legacy_file_name(file_name) then
session_name = (Lib.legacy_unescape_session_name(file_name):gsub("%.vim$", ""))
display_name = session_name .. " (legacy)"
else
session_name = Lib.escaped_session_name_to_session_name(file_name)
display_name = Lib.get_session_display_name(file_name)
end

return {
session_name = session_name,
display_name = display_name,
path = sessions_dir .. file_name,
}
end, entries)
end

---@param files string[]
---@param prompt string
---@param callback fun(choice: PickerItem)
Expand All @@ -89,7 +56,7 @@ end

---@param data table
local function handle_autosession_command(data)
local files = get_session_files()
local files = Lib.get_session_list(M.AutoSession.get_root_dir())
if data.args:match "search" then
open_picker(files, "Select a session:", function(choice)
M.AutoSession.autosave_and_restore(choice.session_name)
Expand All @@ -105,9 +72,12 @@ end
local function purge_orphaned_sessions()
local orphaned_sessions = {}

for _, session in ipairs(get_session_files()) do
local session_files = Lib.get_session_list(M.AutoSession.get_root_dir())
for _, session in ipairs(session_files) do
if
not Lib.is_named_session(session.session_name) and vim.fn.isdirectory(session.session_name) == Lib._VIM_FALSE
not Lib.is_named_session(session.session_name)
-- don't want any annotations (e.g. git branch)
and vim.fn.isdirectory(session.display_name_component) == Lib._VIM_FALSE
then
Lib.logger.debug("purge: " .. session.session_name)
table.insert(orphaned_sessions, session.session_name)
Expand Down
10 changes: 10 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 Expand Up @@ -183,6 +185,7 @@ local function check_old_config_names(config)
and type(config["cwd_change_handling"]) == "table"
and config.cwd_change_handling["restore_upcoming_session"]
then
M.has_old_config = true
local old_cwd_change_handling = config.cwd_change_handling or {} -- shouldn't be nil but placate LS
config["cwd_change_handling"] = old_cwd_change_handling.restore_upcoming_session
if old_cwd_change_handling["pre_cwd_changed_hook"] then
Expand All @@ -192,6 +195,13 @@ local function check_old_config_names(config)
config.post_cwd_changed_cmds = { old_cwd_change_handling.post_cwd_changed_hook }
end
end

if config.session_lens and config.session_lens.shorten_path ~= nil then
M.has_old_config = true
if config.session_lens.shorten_path then
config.session_lens.path_display = { "shorten" }
end
end
end

---@param config? AutoSession.Config
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
77 changes: 77 additions & 0 deletions lua/auto-session/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -604,4 +604,81 @@ function Lib.flatten_table_and_split_strings(input)
return output
end

---Returns the list of files in a directory, sorted by modification time
---@param dir string the directory to list
---@return table The filenames, sorted by modification time
function Lib.sorted_readdir(dir)
-- Get list of files
local files = vim.fn.readdir(dir)

-- Create a table with file names and modification times
local file_times = {}
for _, file in ipairs(files) do
local full_path = dir .. "/" .. file
local mod_time = vim.fn.getftime(full_path)
table.insert(file_times, { name = file, time = mod_time })
end

-- Sort the table based on modification times (most recent first)
table.sort(file_times, function(a, b)
return a.time > b.time
end)

-- Extract just the file names from the sorted table
local sorted_files = {}
for _, file in ipairs(file_times) do
table.insert(sorted_files, file.name)
end

return sorted_files
end

---Get the list of session files. Will filter out any extra command session files
---@param sessions_dir string The directory where the sessions are stored
---@return table the list of session files
function Lib.get_session_list(sessions_dir)
if vim.fn.isdirectory(sessions_dir) == Lib._VIM_FALSE then
return {}
end

local entries = Lib.sorted_readdir(sessions_dir)

return vim.tbl_map(function(file_name)
local session_name
local display_name_component

if not Lib.is_session_file(sessions_dir .. file_name) then
return nil
end

-- an annotation about the session, added to display_name after any path processing
local annotation = ""
if Lib.is_legacy_file_name(file_name) then
session_name = (Lib.legacy_unescape_session_name(file_name):gsub("%.vim$", ""))
display_name_component = session_name
annotation = " (legacy)"
else
session_name = Lib.escaped_session_name_to_session_name(file_name)
display_name_component = session_name
local name_components = Lib.get_session_display_name_as_table(file_name)
if #name_components > 1 then
display_name_component = name_components[1]
annotation = " " .. name_components[2]
end
end

local display_name = display_name_component .. annotation

return {
session_name = session_name,
-- include the components in case telescope wants to shorten the path
display_name_component = display_name_component,
annotation_component = annotation,
display_name = display_name,
file_name = file_name,
path = sessions_dir .. file_name,
}
end, entries)
end

return Lib
22 changes: 20 additions & 2 deletions 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 @@ -66,7 +67,7 @@ M.delete_session = function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:delete_selection(function(selection)
if selection then
AutoSession.DeleteSessionFile(selection.path, selection.display)
AutoSession.DeleteSessionFile(selection.path, selection.display())
end
end)
end
Expand All @@ -92,4 +93,21 @@ 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.session_name)

if not new_name or new_name == "" then
return
end

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)
Loading

0 comments on commit 21e3385

Please sign in to comment.