sort session paths by timestamp and restructure vsplit to be a snippet
authorLukas Hägele <lukas.haegele93@web.de>
Sun, 29 Mar 2026 15:22:22 +0000 (17:22 +0200)
committerLukas Hägele <lukas.haegele93@web.de>
Sun, 29 Mar 2026 15:22:22 +0000 (17:22 +0200)
lua/config/autocommands.lua
lua/config/keymap.lua
lua/snippets/vsplit.lua
plugin/sessionmanager.lua

index cb1985234b4007a04892bde0caa9f0795ace4254..9cab2e71928f61be01cc1310ec8c4a6f8b1b0e6f 100644 (file)
@@ -1,3 +1,51 @@
+-- [vsplit]: create vsplit on startup
+group_vsplit = vim.api.nvim_create_augroup('enforce-single-vsplit', { clear = true }),
+vim.api.nvim_create_autocmd( "VimEnter", {
+  desc = "run explore & create vsplit",
+  group = group_vsplit,
+  callback = function()
+    if vim.bo.filetype ~= "gitcommit" then
+      -- split window on startup
+      local vsplit = require("snippets.vsplit")
+      vsplit.reset{ start_explorer = true }
+    end
+  end
+})
+
+-- [vsplit]: force new window to the left pane
+vim.api.nvim_create_autocmd( "FileType", {
+  desc = "force new window to the left pane",
+  group = group_vsplit,
+  pattern = { "man", "help", "qf" },
+  callback = function()
+    vim.schedule(function()
+      local vsplit = require("snippets.vsplit")
+      local new_win = vim.api.nvim_get_current_win()
+      local new_buf = vim.api.nvim_get_current_buf()
+      if not ((new_win == vsplit.left_id) or (new_win == vsplit.right_id)) then
+        -- move new buffer to left pane
+        vim.api.nvim_win_set_buf(vsplit.left_id, new_buf)
+        -- close new window
+        vim.api.nvim_win_close(new_win, false)
+        -- switch focus
+        if vim.bo.filetype == "qf" then
+          vim.api.nvim_set_current_win(M.right_id)
+        end
+      end
+    end)
+  end
+})
+
+-- [vsplit]: update state if pane is being closed
+vim.api.nvim_create_autocmd( "WinClosed", {
+  desc = "update vsplit state if pane is being closed",
+  group = group_vsplit,
+  callback = function()
+    local vsplit = require("snippets.vsplit")
+    vsplit.check_and_close{ win_id = vim.api.nvim_get_current_win() }
+  end
+})
+
 -- remove trailing whitespace on save
 vim.api.nvim_create_autocmd({ "BufWritePre" }, {
   pattern = { "*" },
index 8aaa3d60980b44ea632e06fc1d1ed867826782b6..5a241bffbc7c2063417c43cda6757d9b4f9c8b1b 100644 (file)
@@ -5,6 +5,9 @@ vim.keymap.set('i', 'jj', '<Esc>')
 vim.keymap.set("n", "<space>#", "Vgc", { desc = "select line and toggle comment", remap = true })
 vim.keymap.set("v", "<space>#", "gc", { desc = "toggle comment of selected line", remap = true })
 
+-- restore vsplit
+vim.keymap.set("n", "<space>s", require("snippets.vsplit").reset, { desc = "split vertically and move to new window" })
+
 -- move highlighted lines
 vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv")
 vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv")
index 50dcde4f825c09f01b48be6924597b00d80eb027..7c68b2f3dbb4118e171d9de0f42a2835831562fc 100644 (file)
@@ -1,58 +1,45 @@
 local M = {}
 
 -- create vsplit
-M.split = function()
-  -- remember window id of left pane for later
-  M.left_id = vim.api.nvim_get_current_win()
-
-  -- Define window configuration
-  local win_config = {
-    vertical = true,
-    split = 'right',
-    width = math.floor(vim.o.columns * 0.6),
-    height = vim.o.lines
-  }
-  -- split window
-  M.right_id = vim.api.nvim_open_win(0, true, win_config)
-end
+M.reset = function(opts)
+  opts = opts or {}
 
--- startup init
-vim.api.nvim_create_autocmd( "VimEnter", {
-  desc = "run explore & create vsplit",
-  callback = function()
-    if vim.bo.filetype ~= "gitcommit" then
-      -- start netrw
-      vim.cmd.Explore()
-      -- split window on startup
-      M.split()
-    end
+  if not (M.left_id and M.right_id) then
+    -- remember window id of left pane for later
+    M.left_id = vim.api.nvim_get_current_win()
+
+    -- Define window configuration
+    local win_config = {
+      vertical = true,
+      split = 'right',
+      width = math.floor(vim.o.columns * 0.6),
+      height = vim.o.lines
+    }
+    -- split window
+    M.right_id = vim.api.nvim_open_win(0, true, win_config)
   end
-})
-
--- force new window to the left pane
-vim.api.nvim_create_autocmd( "FileType", {
-  desc = "force new window to the left pane",
-  group = vim.api.nvim_create_augroup('enforce-single-vsplit', { clear = true }),
-  pattern = { "man", "help", "qf" },
-  callback = function()
-    vim.schedule(function()
-      local new_win = vim.api.nvim_get_current_win()
-      local new_buf = vim.api.nvim_get_current_buf()
-      if not ((new_win == M.left_id) or (new_win == M.right_id)) then
-        -- move new buffer to left pane
-        vim.api.nvim_win_set_buf(M.left_id, new_buf)
-        -- close new window
-        vim.api.nvim_win_close(new_win, false)
-        -- switch focus
-        if vim.bo.filetype == "qf" then
-          vim.api.nvim_set_current_win(M.right_id)
-        end
-      end
-    end)
+
+  if opts.start_explorer then
+    local start_explorer = function(win_id, cwd)
+      vim.api.nvim_set_current_win(win_id)
+      vim.cmd.Explore(cwd)
+    end
+
+    local cwd = vim.fn.getcwd()
+    start_explorer(M.left_id, cwd)
+    start_explorer(M.right_id, cwd)
   end
-})
+end
+
+-- update state if pane is being closed
+M.check_and_close = function(opts)
+  opts = opts or {}
 
--- keymaps
-vim.keymap.set("n", "<space>s", M.split, { desc = "split vertically and move to new window" })
+  if (opts.win_id == M.left_id) then
+    M.left_id = nil
+  elseif (opts.win_id == M.right_id) then
+    M.right_id = nil
+  end
+end
 
 return M
index 865e4ad14fa80979e20433d592014a9e3cdebec5..18504ec3e8264759254618eb94ed3f686b314a12 100644 (file)
@@ -6,20 +6,32 @@ local action_state = require "telescope.actions.state"
 
 local history = {}
 
---- show session history in telescope
+-- show session history in telescope
 local function session_picker(opts)
   opts = opts or require("telescope.themes").get_dropdown{}
 
-  -- rearrange history
+  -- rearrange history to array of tables
   local results = {}
-  for entry_path, _ in pairs(history) do
-    table.insert(results, entry_path)
+  for _, value in pairs(history) do
+    table.insert(results, value)
   end
 
+  -- sort table in descending order
+  table.sort(results, function(a, b)
+    return (a.timestamp or 0) > (b.timestamp or 0)
+  end)
+
   pickers.new(opts, {
     prompt_title = "session history",
     finder = finders.new_table {
       results = results,
+      entry_maker = function(entry)
+        return {
+          value = entry,
+          display = entry.path,
+          ordinal = entry.path
+        }
+      end
     },
 
     sorter = conf.generic_sorter(opts),
@@ -28,22 +40,21 @@ local function session_picker(opts)
       actions.select_default:replace(function()
         actions.close(prompt_bufnr)
 
-        -- close all splits (by closing all other windows)
-        vim.cmd("only")
-
         -- close all buffers
         vim.cmd("bufdo bdelete")
 
         local selection = action_state.get_selected_entry()
-        local dir = selection[1]
+        local entry = selection.value
+
         -- change the current directory
-        vim.cmd("cd" ..dir)
+        vim.cmd("cd" ..entry.path)
+        while vim.fn.getcwd() ~= entry.path do
+          print("waiting...")
+        end
 
-        -- start file browser
-        vim.cmd.Explore(dir)
         -- split window
         local vsplit = require("snippets.vsplit")
-        vsplit.split()
+        vsplit.reset{ start_explorer = true }
       end)
       return true
     end
@@ -53,7 +64,7 @@ end
 -- read and update history file on disk
 do
   local history_dir = vim.fn.stdpath("state") .."/sessionmanager/"
-  local history_file = history_dir .. "history.lua"
+  local history_file = history_dir .."history.lua"
 
   -- read history from disk
   do
@@ -69,28 +80,24 @@ do
     local function serialize()
       local str = ""
       for _, entry in pairs(history) do
-        str = str .. "Project { path = \"" .. entry.path .. "\" }\n"
+        str = str .."Project { path = \"" ..entry.path .."\", timestamp = " ..(entry.timestamp or "nil") .." }\n"
       end
 
       return str
     end
 
     local cwd = vim.fn.getcwd()
-    -- TODO: only save, when nvim was opened in a directory?
-    -- check if directory is opened for the first time
-    if history[cwd] == nil then
-      local entry = { path = cwd }
-      history[cwd] = entry
-
-      -- serialize history
-      local history_str = serialize()
-
-      -- write to disk
-      vim.fn.mkdir(history_dir, "p")
-      local f = assert(io.open(history_file, "w"))
-      f:write(history_str)
-      f:close()
-    end
+    local entry = { path = cwd, timestamp = os.time() }
+    history[cwd] = entry
+
+    -- serialize history
+    local history_str = serialize()
+
+    -- write to disk
+    vim.fn.mkdir(history_dir, "p")
+    local f = assert(io.open(history_file, "w"))
+    f:write(history_str)
+    f:close()
   end
 end