diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-08 17:22:58 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-08 17:22:58 +0200 |
| commit | 798350bf21ba4ecc5cb2b16218be86122b17f5ab (patch) | |
| tree | ab21100406b5df49340f3bccaec0abeb88ede224 /.config/nvim/plugin/50-session.lua | |
| parent | f19105e4bfc0695d6f9816c1f2233bb2c8a7ad8c (diff) | |
| download | dotfiles-798350bf21ba4ecc5cb2b16218be86122b17f5ab.tar.gz dotfiles-798350bf21ba4ecc5cb2b16218be86122b17f5ab.zip | |
feat(nvim): sessions restoration include man pages
Diffstat (limited to '.config/nvim/plugin/50-session.lua')
| -rw-r--r-- | .config/nvim/plugin/50-session.lua | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/.config/nvim/plugin/50-session.lua b/.config/nvim/plugin/50-session.lua index 9d1a8bf..39b4c09 100644 --- a/.config/nvim/plugin/50-session.lua +++ b/.config/nvim/plugin/50-session.lua @@ -36,6 +36,32 @@ local function write_sidecar(path, data) end end +-- :mksession can't restore man:// buffers (they're :buftype=nofile, not backed by a file), so +-- we record them ourselves, nested as tab index -> window number -> { buffer name, cursor line }. +-- Both indices are positional for the same reason as tab names above: :mksession recreates tabs +-- and their windows in order, so the ordinals are stable across reloads. Nesting by tab matters +-- because window numbers restart at 1 in each tabpage and would otherwise collide. The indices +-- are stringified so the sparse table encodes as a JSON object, not a null-padded array. +-- +-- Limitation: the cursor line is an index into the *rendered* man page, whose line wrapping +-- depends on MANWIDTH. If MANWIDTH differs on load, the page re-wraps and the saved line points +-- elsewhere. (It never changes in this setup, but the dependency is real.) +local function man_windows() + local pages = {} + for ti, tp in ipairs(vim.api.nvim_list_tabpages()) do + for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tp)) do + local name = vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(win)) + if name:match("^man://") then + local tk = tostring(ti) + pages[tk] = pages[tk] or {} + pages[tk][tostring(vim.api.nvim_win_get_number(win))] = + { name = name, line = vim.api.nvim_win_get_cursor(win)[1] } + end + end + end + return pages +end + local function save_session(path) vim.cmd.mksession({ path, bang = true }) local names = {} @@ -44,21 +70,52 @@ local function save_session(path) local ok, name = pcall(vim.api.nvim_tabpage_get_var, tp, "tabname") names[i] = (ok and type(name) == "string") and name or "" end - write_sidecar(path, { tabnames = names }) + write_sidecar(path, { tabnames = names, manpages = man_windows() }) end -local function load_session(path) - vim.cmd.source(path) - local names = read_sidecar(path).tabnames - if not names then +-- Reopen the man:// buffers recorded by man_windows(). Keys come back from JSON as strings, +-- hence the tonumber(). :edit man://... re-renders the page via the man plugin's BufReadCmd; we +-- run it window-scoped so the layout restored by :mksession is left untouched, then clamp the +-- saved cursor line to the (possibly re-wrapped) page. +local function restore_man_windows(manpages) + if not manpages then return end - 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]) + local tabpages = vim.api.nvim_list_tabpages() + for tk, wins in pairs(manpages) do + local tp = tabpages[tonumber(tk)] + if tp then + local by_number = {} + for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tp)) do + by_number[vim.api.nvim_win_get_number(win)] = win + end + for wk, info in pairs(wins) do + local win = by_number[tonumber(wk)] + if win then + vim.api.nvim_win_call(win, function() + vim.cmd.edit({ args = { info.name } }) + end) + local buf = vim.api.nvim_win_get_buf(win) + local line = math.max(1, math.min(info.line or 1, vim.api.nvim_buf_line_count(buf))) + vim.api.nvim_win_set_cursor(win, { line, 0 }) + end + end + end + end +end + +local function load_session(path) + vim.cmd.source(path) + local data = read_sidecar(path) + if data.tabnames then + for i, tp in ipairs(vim.api.nvim_list_tabpages()) do + if data.tabnames[i] and data.tabnames[i] ~= "" then + vim.api.nvim_tabpage_set_var(tp, "tabname", data.tabnames[i]) + end end + vim.cmd.redrawtabline() end - vim.cmd.redrawtabline() + restore_man_windows(data.manpages) end local function reload_session(path) |
