From aed9eee722e118284df1099043538c884d7b76a6 Mon Sep 17 00:00:00 2001 From: hlstwizard Date: Fri, 3 Apr 2026 11:32:21 +0800 Subject: [PATCH] Add auto-session with layout-aware focus restore --- lazy-lock.json | 20 ++++----- lua/custom/layout.lua | 52 +++++++++++++++++++--- lua/custom/plugins/enable/auto_session.lua | 45 +++++++++++++++++++ 3 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 lua/custom/plugins/enable/auto_session.lua diff --git a/lazy-lock.json b/lazy-lock.json index f4f0461f..de7d6edb 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -1,32 +1,32 @@ { "LuaSnip": { "branch": "master", "commit": "5a1e39223db9a0498024a77b8441169d260c8c25" }, + "auto-session": { "branch": "main", "commit": "62437532b38495551410b3f377bcf4aaac574ebe" }, "blame.nvim": { "branch": "main", "commit": "179da7aaacce7c52874af636255ede72dd6fe796" }, "blink.cmp": { "branch": "main", "commit": "451168851e8e2466bc97ee3e026c3dcb9141ce07" }, - "codediff.nvim": { "branch": "main", "commit": "93cd80c56f71af4671388c568a37d4c84c3ddefa" }, + "codediff.nvim": { "branch": "main", "commit": "832f1ecc5f8b15a44cf7537e31d3266d657775b1" }, "conform.nvim": { "branch": "master", "commit": "086a40dc7ed8242c03be9f47fbcee68699cc2395" }, "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" }, - "fidget.nvim": { "branch": "main", "commit": "7fa433a83118a70fe24c1ce88d5f0bd3453c0970" }, - "gitsigns.nvim": { "branch": "main", "commit": "50c205548d8b037b7ff6378fca6d21146f0b6161" }, + "fidget.nvim": { "branch": "main", "commit": "889e2e96edef4e144965571d46f7a77bcc4d0ddf" }, + "gitsigns.nvim": { "branch": "main", "commit": "e1fb5425c8812214209b3f24eaa582c6c552cf98" }, "guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" }, "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "037398b9ce4a53ba48d5f94765c641a1fd16d906" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "25f609e7fca78af7cede4f9fa3af8a94b1c4950b" }, "mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" }, "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, - "mini.nvim": { "branch": "main", "commit": "af5f75c9ce572a4d1f0c77d6fb4ea764d16c1b3c" }, + "mini.nvim": { "branch": "main", "commit": "3923662bf3d6ca49a9503f8d7196ea0450983e6a" }, "neo-tree.nvim": { "branch": "main", "commit": "84c75e7a7e443586f60508d12fc50f90d9aee14e" }, "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, "nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" }, "nvim-lint": { "branch": "master", "commit": "4b03656c09c1561f89b6aa0665c15d292ba9499d" }, - "nvim-lspconfig": { "branch": "master", "commit": "16812abf0e8d8175155f26143a8504e8253e92b0" }, - "nvim-treesitter": { "branch": "main", "commit": "7caec274fd19c12b55902a5b795100d21531391f" }, - "nvim-web-devicons": { "branch": "master", "commit": "d7462543c9e366c0d196c7f67a945eaaf5d99414" }, + "nvim-lspconfig": { "branch": "master", "commit": "8e2084bf5e40c79c1f42210a6ef96a0a4793a763" }, + "nvim-treesitter": { "branch": "main", "commit": "539abf6da5ee8702e37b82cc953131dadd570da2" }, + "nvim-web-devicons": { "branch": "master", "commit": "40e9d5a6cc3db11b309e39593fc7ac03bb844e38" }, "opencode.nvim": { "branch": "main", "commit": "df533d6da724109bf08446392db860fdceddbd0c" }, - "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" }, "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, "telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" }, "telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" }, - "telescope.nvim": { "branch": "master", "commit": "e6cdb4dc528c5dc4ca8da86e83ef4e3c84b0729c" }, + "telescope.nvim": { "branch": "master", "commit": "cfb85dcf7f822b79224e9e6aef9e8c794211b20b" }, "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, "toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" }, "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, diff --git a/lua/custom/layout.lua b/lua/custom/layout.lua index 217f2226..8a0a785d 100644 --- a/lua/custom/layout.lua +++ b/lua/custom/layout.lua @@ -8,12 +8,18 @@ local sidebar_filetypes = { ['opencode'] = true, } +function M.is_main_window(win) + if not win or not vim.api.nvim_win_is_valid(win) then return false end + + local buf = vim.api.nvim_win_get_buf(win) + local ft = vim.bo[buf].filetype + local bt = vim.bo[buf].buftype + return not sidebar_filetypes[ft] and bt == '' +end + function M.focus_main_window() for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do - local buf = vim.api.nvim_win_get_buf(win) - local ft = vim.bo[buf].filetype - local bt = vim.bo[buf].buftype - if not sidebar_filetypes[ft] and bt == '' then + if M.is_main_window(win) then vim.api.nvim_set_current_win(win) return true end @@ -31,6 +37,38 @@ local function find_window_by_filetype(filetype) return nil end +function M.capture_focus() + local current_win = vim.api.nvim_get_current_win() + if not M.is_main_window(current_win) then return nil end + + local buf = vim.api.nvim_win_get_buf(current_win) + local buf_name = vim.api.nvim_buf_get_name(buf) + if buf_name == '' then return nil end + + return { + buf_name = buf_name, + } +end + +function M.restore_focus(focus) + if type(focus) ~= 'table' then return M.focus_main_window() end + + local target_buf_name = focus.buf_name + if type(target_buf_name) ~= 'string' or target_buf_name == '' then return M.focus_main_window() end + + for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do + if M.is_main_window(win) then + local buf = vim.api.nvim_win_get_buf(win) + if vim.api.nvim_buf_get_name(buf) == target_buf_name then + vim.api.nvim_set_current_win(win) + return true + end + end + end + + return M.focus_main_window() +end + local function ensure_neotree_window() local neotree_win = find_window_by_filetype 'neo-tree' if neotree_win then return neotree_win end @@ -59,7 +97,9 @@ local function ensure_opencode_window() return find_window_by_filetype 'opencode' end -function M.reset_ide_layout() +function M.reset_ide_layout(opts) + opts = opts or {} + local neotree_win = ensure_neotree_window() local opencode_win = ensure_opencode_window() @@ -77,7 +117,7 @@ function M.reset_ide_layout() if neotree_win and vim.api.nvim_win_is_valid(neotree_win) then vim.api.nvim_win_set_width(neotree_win, left_width) end if opencode_win and vim.api.nvim_win_is_valid(opencode_win) then vim.api.nvim_win_set_width(opencode_win, right_width) end - M.focus_main_window() + if opts.focus_main ~= false then M.focus_main_window() end end return M diff --git a/lua/custom/plugins/enable/auto_session.lua b/lua/custom/plugins/enable/auto_session.lua new file mode 100644 index 00000000..1ba07b14 --- /dev/null +++ b/lua/custom/plugins/enable/auto_session.lua @@ -0,0 +1,45 @@ +return { + { + 'rmagatti/auto-session', + lazy = false, + + ---enables autocomplete for opts + ---@module 'auto-session' + ---@type AutoSession.Config + opts = { + suppressed_dirs = { '~/', '~/Downloads', '/' }, + -- Keep sessions even when only a directory/sidebar is open (IDE-style usage). + auto_delete_empty_sessions = false, + save_extra_data = function(_) + local ok, layout = pcall(require, 'custom.layout') + if not ok then return nil end + + local focus = layout.capture_focus() + if not focus then return nil end + + return vim.fn.json_encode { + focus = focus, + } + end, + restore_extra_data = function(_, extra_data) + local ok_json, decoded = pcall(vim.fn.json_decode, extra_data) + if not ok_json or type(decoded) ~= 'table' then return end + + local ok_layout, layout = pcall(require, 'custom.layout') + if not ok_layout then return end + + local focus = decoded.focus + if type(focus) == 'table' then vim.schedule(function() layout.restore_focus(focus) end) end + end, + post_restore_cmds = { + function(_) + local ok_layout, layout = pcall(require, 'custom.layout') + if not ok_layout then return end + + vim.schedule(function() layout.reset_ide_layout { focus_main = false } end) + end, + }, + -- log_level = 'debug', + }, + }, +}