-- -- Session plugin -- local session_dir = vim.fn.stdpath("state") .. "/sessions" local session_default = session_dir .. "/default.vim" if not vim.uv.fs_stat(session_dir) then vim.uv.fs_mkdir(session_dir, tonumber("755", 8)) vim.notify("Sessions save directory created at " .. session_dir) end -- :mksession doesn't persist tab-local vars (t:tabname), so we write tab names to a sidecar -- JSON file alongside the .vim session. Names are stored positionally because :mksession -- recreates tabs in their original order, making the index stable across reloads. local function tabnames_path(path) return (path:gsub("%.vim$", "")) .. ".tabnames.json" end local function save_session(path) vim.cmd.mksession({ path, bang = true }) local names = {} for i, tp in ipairs(vim.api.nvim_list_tabpages()) do -- pcall: nvim_tabpage_get_var errors when the variable isn't set on that tab local ok, name = pcall(vim.api.nvim_tabpage_get_var, tp, "tabname") names[i] = (ok and type(name) == "string") and name or "" end local f = io.open(tabnames_path(path), "w") if f then f:write(vim.json.encode(names)) f:close() end end local function load_session(path) vim.cmd.source(path) local f = io.open(tabnames_path(path), "r") if not f then return end local names = vim.json.decode(f:read("*a")) f:close() for i, tp in ipairs(vim.api.nvim_list_tabpages()) do if names[i] and names[i] ~= "" then vim.api.nvim_tabpage_set_var(tp, "tabname", names[i]) end end vim.cmd.redrawtabline() end local function reload_session(path) save_session(path) vim.cmd.restart({ args = { "+qall", "SessionLoad", path } }) end local function delete_session(path) vim.fs.rm(path) local sidecar = tabnames_path(path) if vim.uv.fs_stat(sidecar) then vim.fs.rm(sidecar) end end local function session_completefunc(arg_lead, _, _) local completions = {} for path in vim.fs.dir(session_dir) do if string.match(path, "^" .. arg_lead) and string.match(path, ".vim$") then completions[#completions + 1] = path:sub(1, -5) end end return completions end local function session_op(base, op) local path = #base > 0 and base or session_default if not string.match(path, "^" .. session_dir) then path = session_dir .. "/" .. path end if not string.match(path, "%.vim$") then path = path .. ".vim" end op(path) end vim.api.nvim_create_user_command("SessionSave", function(ev) session_op(ev.args, save_session) end, { desc = "Save session", nargs = "?", complete = session_completefunc }) vim.api.nvim_create_user_command("SessionLoad", function(ev) session_op(ev.args, load_session) end, { desc = "Load session", nargs = "?", complete = session_completefunc }) vim.api.nvim_create_user_command("SessionDelete", function(ev) session_op(ev.args, delete_session) end, { desc = "Delete session", nargs = "?", complete = session_completefunc }) vim.api.nvim_create_user_command("SessionRestart", function(ev) session_op(ev.args, reload_session) end, { desc = "Reload session", nargs = "?", complete = session_completefunc }) vim.api.nvim_create_user_command("SessionExitSave", function(ev) session_op(ev.args, save_session) vim.cmd.qall() end, { desc = "Save session and exit", nargs = "?", complete = session_completefunc }) vim.api.nvim_create_user_command("SessionExitNoSave", function() vim.cmd.qall() end, { desc = "Exit without saving session", nargs = "?", complete = session_completefunc })