diff --git a/lua/auto-session/init.lua b/lua/auto-session/init.lua index 1805740..b73089e 100644 --- a/lua/auto-session/init.lua +++ b/lua/auto-session/init.lua @@ -420,8 +420,7 @@ local function get_session_file_name(session_name, legacy) local git_branch_name = get_git_branch_name() if git_branch_name and git_branch_name ~= "" then - -- TODO: Should find a better way to encode branch name - session_name = session_name .. " " .. git_branch_name + session_name = session_name .. "|" .. git_branch_name end end @@ -590,8 +589,8 @@ local function get_session_files() session_name = (Lib.legacy_unescape_session_name(file_name):gsub("%.vim$", "")) display_name = session_name .. " (legacy)" else - session_name = Lib.session_file_name_to_session_name(file_name) - display_name = session_name + session_name = Lib.escaped_session_name_to_session_name(file_name) + display_name = Lib.get_session_display_name(file_name) end return { @@ -833,7 +832,7 @@ function AutoSession.SaveSessionToDir(session_dir, session_name, show_message) -- session_name might be nil (e.g. when using cwd), unescape escaped_session_name instead Lib.logger.debug("Saved session: " .. Lib.unescape_session_name(escaped_session_name)) if show_message == nil or show_message then - vim.notify("Saved session: " .. Lib.unescape_session_name(escaped_session_name)) + vim.notify("Saved session: " .. Lib.get_session_display_name(escaped_session_name)) end return true @@ -875,14 +874,14 @@ function AutoSession.RestoreSessionFromDir(session_dir, session_name, show_messa if vim.fn.filereadable(legacy_session_path) ~= 1 then if show_message == nil or show_message then - vim.notify("Could not restore session: " .. Lib.session_file_name_to_session_name(escaped_session_name)) + vim.notify("Could not restore session: " .. Lib.get_session_display_name(escaped_session_name)) end return false end Lib.logger.debug("RestoreSessionFromDir renaming legacy session: " .. legacy_escaped_session_name) ---@diagnostic disable-next-line: undefined-field - if not vim.uv.fs_rename(legacy_session_path, session_path) then + if not vim.loop.fs_rename(legacy_session_path, session_path) then Lib.logger.debug( "RestoreSessionFromDir rename failed!", { session_path = session_path, legacy_session_path = legacy_session_path } @@ -933,7 +932,7 @@ Disabling auto save. Please check for errors in your config. Error: -- session_name might be nil (e.g. when using cwd), unescape escaped_session_name instead Lib.logger.debug("Restored session: " .. Lib.unescape_session_name(escaped_session_name)) if show_message == nil or show_message then - vim.notify("Restored session: " .. Lib.session_file_name_to_session_name(escaped_session_name)) + vim.notify("Restored session: " .. Lib.get_session_display_name(escaped_session_name)) end local post_cmds = AutoSession.get_cmds "post_restore" @@ -975,7 +974,7 @@ function AutoSession.DeleteSessionFromDir(session_dir, session_name) local legacy_session_path = session_dir .. legacy_escaped_session_name if vim.fn.filereadable(legacy_session_path) ~= 1 then - vim.notify("Could not session to delete: " .. Lib.session_file_name_to_session_name(escaped_session_name)) + vim.notify("Could not session to delete: " .. Lib.get_session_display_name(escaped_session_name)) return false end Lib.logger.debug("DeleteSessionFromDir using legacy session: " .. legacy_escaped_session_name) diff --git a/lua/auto-session/lib.lua b/lua/auto-session/lib.lua index 898b772..18c3b5d 100644 --- a/lua/auto-session/lib.lua +++ b/lua/auto-session/lib.lua @@ -25,7 +25,7 @@ end function Lib.current_session_name() -- get the filename without the extension local file_name = vim.fn.fnamemodify(vim.v.this_session, ":t:r") - return Lib.unescape_session_name(file_name) + return Lib.get_session_display_name(file_name) end function Lib.is_empty_table(t) @@ -105,7 +105,7 @@ end ---because dashes in the session name are lost ---@param dir string Session name to be unescaped ---@return string The unescaped session name -local function win32_unescaped_dir(dir) +local function legacy_win32_unescaped_dir(dir) dir = dir:gsub("++", ":") if not vim.o.shellslash then dir = dir:gsub("-", "\\") @@ -119,7 +119,7 @@ end ---because dashes in the session name are lost ---@param dir string Session name to be escaped ---@return string The escaped session name -local function win32_escaped_dir(dir) +local function legacy_win32_escaped_dir(dir) dir = dir:gsub(":", "++") if not vim.o.shellslash then dir = dir:gsub("\\", "-") @@ -192,7 +192,7 @@ end ---@return string The escaped string function Lib.legacy_escape_session_name(session_name) if IS_WIN32 then - return win32_escaped_dir(session_name) + return legacy_win32_escaped_dir(session_name) end return (session_name:gsub("/", "%%")) @@ -204,7 +204,7 @@ end ---@return string The unescaped string function Lib.legacy_unescape_session_name(escaped_session_name) if IS_WIN32 then - return win32_unescaped_dir(escaped_session_name) + return legacy_win32_unescaped_dir(escaped_session_name) end return (escaped_session_name:gsub("%%", "/")) @@ -270,7 +270,7 @@ function Lib.convert_session_dir(session_dir) Lib.logger.debug("File already exists! ", new_file_path) else ---@diagnostic disable-next-line: undefined-field - local ok, err = vim.uv.fs_rename(session_dir .. old_file_name, new_file_path) + local ok, err = vim.loop.fs_rename(session_dir .. old_file_name, new_file_path) if not ok then Lib.logger.error("Failed to move old session: " .. old_file_path " to new format. Error: " .. err) else @@ -353,12 +353,38 @@ function Lib.close_unsupported_windows() end end ----Convert a session file name to a session_name, which is useful for display ----and can also be passed to SessionRestore/Delete ----@param session_file_name string The session file name. It should not have a path component +---Convert a session file name to a session_name that passed to SessionRestore/Delete. +---Although, those commands should also take a session name ending in .vim +---@param escaped_session_name string The session file name. It should not have a path component ---@return string The session name, suitable for display or passing to other cmds -function Lib.session_file_name_to_session_name(session_file_name) - return (Lib.unescape_session_name(session_file_name):gsub("%.vim$", "")) +function Lib.escaped_session_name_to_session_name(escaped_session_name) + return (Lib.unescape_session_name(escaped_session_name):gsub("%.vim$", "")) +end + +---Get the session displayname as a table of components. Index 1 will always be the session +---name (but not file name) with any annotations coming after (like git branch) +---@param escaped_session_name string The session file name. It should not have a path component +---@return table The session name components +function Lib.get_session_display_name_as_table(escaped_session_name) + -- sesssion name contains a |, split on that and get git branch + local session_name = Lib.escaped_session_name_to_session_name(escaped_session_name) + local splits = vim.split(session_name, "|") + + if #splits == 1 then + return splits + end + + splits[2] = "(branch: " .. splits[2] .. ")" + return splits +end +---Convert a session file name to a display name The result cannot be used with commands +---like SessionRestore/SessionDelete as it might have additional annotations (like a git branch) +---@param escaped_session_name string The session file name. It should not have a path component +---@return string The session name suitable for display +function Lib.get_session_display_name(escaped_session_name) + local splits = Lib.get_session_display_name_as_table(escaped_session_name) + + return table.concat(splits, " ") end ---Returns if a session is a named session or not (i.e. from a cwd) diff --git a/lua/auto-session/session-lens/actions.lua b/lua/auto-session/session-lens/actions.lua index 7c81e3a..7428f73 100644 --- a/lua/auto-session/session-lens/actions.lua +++ b/lua/auto-session/session-lens/actions.lua @@ -79,7 +79,7 @@ M.alternate_session = function(prompt_bufnr) if Lib.is_legacy_file_name(file_name) then session_name = (Lib.legacy_unescape_session_name(file_name):gsub("%.vim$", "")) else - session_name = Lib.session_file_name_to_session_name(file_name) + session_name = Lib.escaped_session_name_to_session_name(file_name) end source_session(session_name, prompt_bufnr) diff --git a/lua/auto-session/session-lens/init.lua b/lua/auto-session/session-lens/init.lua index 6ebc9c8..09ff4f6 100644 --- a/lua/auto-session/session-lens/init.lua +++ b/lua/auto-session/session-lens/init.lua @@ -47,16 +47,28 @@ local function make_telescope_callback(opts) return nil end + -- the name of the session, to be used for restoring/deleting local session_name + + -- the name to display, possibly with a shortened path + local display_name + + -- an annotation about the sesssion, 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 = session_name annotation = " (legacy)" else - session_name = Lib.session_file_name_to_session_name(file_name) + session_name = Lib.escaped_session_name_to_session_name(file_name) + display_name = session_name + local name_components = Lib.get_session_display_name_as_table(file_name) + if #name_components > 1 then + display_name = name_components[1] + annotation = " " .. name_components[2] + end end - local display_name = session_name if opts.path_display and vim.tbl_contains(opts.path_display, "shorten") then display_name = path:new(display_name):shorten() if not display_name then diff --git a/tests/git_spec.lua b/tests/git_spec.lua index 6ba0eab..1e2652d 100644 --- a/tests/git_spec.lua +++ b/tests/git_spec.lua @@ -49,12 +49,16 @@ describe("The git config", function() it("saves a session with the branch name", function() -- vim.cmd ":SessionSave" - require("auto-session").AutoSaveSession() + local as = require "auto-session" - local session_path = TL.session_dir .. TL.escapeSessionName(vim.fn.getcwd() .. " main.vim") + as.AutoSaveSession() + + local session_path = TL.session_dir .. TL.escapeSessionName(vim.fn.getcwd() .. "|main.vim") print(session_path) assert.equals(1, vim.fn.filereadable(session_path)) + + assert.equals(vim.fn.getcwd() .. " (branch: main)", as.Lib.current_session_name()) end) end) diff --git a/tests/legacy_file_names_spec.lua b/tests/legacy_file_names_spec.lua index 4a7f652..7d1bc50 100644 --- a/tests/legacy_file_names_spec.lua +++ b/tests/legacy_file_names_spec.lua @@ -55,7 +55,7 @@ describe("Legacy file name support", function() as.SaveSession() assert.equals(1, vim.fn.filereadable(TL.default_session_path)) - vim.uv.fs_rename(TL.default_session_path, TL.default_session_path_legacy) + vim.loop.fs_rename(TL.default_session_path, TL.default_session_path_legacy) assert.equals(1, vim.fn.filereadable(TL.default_session_path_legacy)) assert.equals(0, vim.fn.filereadable(TL.default_session_path)) diff --git a/tests/lib_spec.lua b/tests/lib_spec.lua index 200247c..aa427c0 100644 --- a/tests/lib_spec.lua +++ b/tests/lib_spec.lua @@ -43,10 +43,32 @@ describe("Lib / Helper functions", function() assert.equals(nil, as.Lib.get_latest_session(TL.session_dir)) end) + it("can urlencode/urldecode", function() + assert.equals("%2Fsome%2Fdir%2Fwith%20spaces%2Fand-dashes", Lib.urlencode "/some/dir/with spaces/and-dashes") + assert.equals("/some/dir/with spaces/and-dashes", Lib.urldecode(Lib.urlencode "/some/dir/with spaces/and-dashes")) + + assert.equals( + "c%3A%5Csome%5Cdir%5Cwith%20space%5Cand-dashes%5C", + Lib.urlencode "c:\\some\\dir\\with space\\and-dashes\\" + ) + assert.equals( + "c:\\some\\dir\\with space\\and-dashes\\", + Lib.urldecode(Lib.urlencode "c:\\some\\dir\\with space\\and-dashes\\") + ) + + -- round trip should be stable + assert.equals(TL.default_session_name, Lib.urldecode(Lib.urlencode(TL.default_session_name))) + assert.equals(TL.named_session_name, Lib.urldecode(Lib.urlencode(TL.named_session_name))) + + -- Should not encode anything + assert.equals(TL.named_session_name, Lib.urldecode(TL.named_session_name)) + assert.equals(TL.named_session_name, Lib.urlencode(TL.named_session_name)) + end) + it("session_file_name_to_session_name() works", function() - assert.equals("mysession", Lib.session_file_name_to_session_name "mysession.vim") - assert.equals("mysessionavim", Lib.session_file_name_to_session_name "mysessionavim") - assert.equals("mysession", Lib.session_file_name_to_session_name "mysession") + assert.equals("mysession", Lib.escaped_session_name_to_session_name "mysession.vim") + assert.equals("mysessionavim", Lib.escaped_session_name_to_session_name "mysessionavim") + assert.equals("mysession", Lib.escaped_session_name_to_session_name "mysession") end) it("is_named_session() works", function() @@ -93,28 +115,6 @@ describe("Lib / Helper functions", function() assert.equals("\\%some\\%dir\\%", Lib.escape_string_for_vim "%some%dir%") end) - it("can urlencode/urldecode", function() - assert.equals("%2Fsome%2Fdir%2Fwith%20spaces%2Fand-dashes", Lib.urlencode "/some/dir/with spaces/and-dashes") - assert.equals("/some/dir/with spaces/and-dashes", Lib.urldecode(Lib.urlencode "/some/dir/with spaces/and-dashes")) - - assert.equals( - "c%3A%5Csome%5Cdir%5Cwith%20space%5Cand-dashes%5C", - Lib.urlencode "c:\\some\\dir\\with space\\and-dashes\\" - ) - assert.equals( - "c:\\some\\dir\\with space\\and-dashes\\", - Lib.urldecode(Lib.urlencode "c:\\some\\dir\\with space\\and-dashes\\") - ) - - -- round trip should be stable - assert.equals(TL.default_session_name, Lib.urldecode(Lib.urlencode(TL.default_session_name))) - assert.equals(TL.named_session_name, Lib.urldecode(Lib.urlencode(TL.named_session_name))) - - -- Should not encode anything - assert.equals(TL.named_session_name, Lib.urldecode(TL.named_session_name)) - assert.equals(TL.named_session_name, Lib.urlencode(TL.named_session_name)) - end) - it("can identify new and old sessions", function() assert.False(Lib.is_legacy_file_name(Lib.urlencode "mysession" .. ".vim")) assert.False(Lib.is_legacy_file_name(Lib.urlencode "/some/dir/" .. ".vim")) @@ -132,4 +132,27 @@ describe("Lib / Helper functions", function() assert.True(Lib.is_legacy_file_name(TL.legacyEscapeSessionName "c:/some/dir-with-dashes" .. ".vim")) end end) + + it("can get display name", function() + local splits = Lib.get_session_display_name_as_table "%2FUsers%2Fcam%2FDev%2Fneovim-dev%2Fauto-session.vim" + + assert.equals(1, #splits) + assert.equals("/Users/cam/Dev/neovim-dev/auto-session", splits[1]) + + assert.equals( + "/Users/cam/tmp/a (branch: main)", + (Lib.get_session_display_name "%2FUsers%2Fcam%2Ftmp%2Fa%7Cmain.vim") + ) + + splits = Lib.get_session_display_name_as_table "%2FUsers%2Fcam%2Ftmp%2Fa%7Cmain.vim" + + assert.equals(2, #splits) + assert.equals("/Users/cam/tmp/a", splits[1]) + assert.equals("(branch: main)", splits[2]) + + assert.equals( + "/Users/cam/tmp/a (branch: main)", + (Lib.get_session_display_name "%2FUsers%2Fcam%2Ftmp%2Fa%7Cmain.vim") + ) + end) end)