summaryrefslogtreecommitdiffstats
path: root/lua/dotfiles/session.lua
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-06-24 19:59:53 +0200
committerThomas Vanbesien <tvanbesi@proton.me>2026-06-24 20:06:02 +0200
commit046e3be5982104f9e889edf1490381ea8c3b959f (patch)
tree0ba6307103e243c6cd688dc1fb631df5f82a17aa /lua/dotfiles/session.lua
parentc4ff1dc44373f03e8e940670f9610a6005d960b0 (diff)
downloadnvim-config-046e3be5982104f9e889edf1490381ea8c3b959f.tar.gz
nvim-config-046e3be5982104f9e889edf1490381ea8c3b959f.zip
refactor(nvim): rewrite session plugin
Diffstat (limited to 'lua/dotfiles/session.lua')
-rw-r--r--lua/dotfiles/session.lua78
1 files changed, 78 insertions, 0 deletions
diff --git a/lua/dotfiles/session.lua b/lua/dotfiles/session.lua
new file mode 100644
index 0000000..4333978
--- /dev/null
+++ b/lua/dotfiles/session.lua
@@ -0,0 +1,78 @@
+-- Sidecar specification for :mksession. :mksession can't persist everything we want (tab-local
+-- variables, man:// buffers, ...), so we keep a JSON object in a sidecar file alongside each `.vim`
+-- session. Features register a `save`/`restore` pair: `save` returns the data to stash, `restore`
+-- reapplies it after the session has been sourced. The engine owns reading, writing and dispatch;
+-- it does not touch :mksession itself. Providers are wired up in plugin/50-session.lua.
+--
+-- API:
+-- register(key, save, restore) — add a provider (provider contract below)
+-- write(path) — collect every provider and write `path`'s sidecar
+-- read(path) — read `path`'s sidecar and run each provider's restore
+-- remove(path) — delete `path`'s sidecar if it exists
+-- providers — the ordered registry: a list of { key, save, restore }
+
+local M = {}
+
+-- Ordered registry of sidecar providers (the "global table"):
+-- { key = string, save = fun(): table, restore = fun(data: table) }
+-- `save` returns a JSON-encodable table stored under `key`; `restore` receives it back (never nil)
+-- after the session is sourced. Registration order is the restore order.
+M.providers = {}
+
+-- The sidecar JSON path that pairs with a `.vim` session file.
+local function sidecar_path(path)
+ return (path:gsub("%.vim$", "")) .. ".json"
+end
+
+-- Register a sidecar provider. `save` and `restore` are both required (passed together) so a
+-- provider can never be half-defined.
+function M.register(key, save, restore)
+ assert(
+ type(save) == "function" and type(restore) == "function",
+ "session.register: both save and restore are required"
+ )
+ M.providers[#M.providers + 1] = { key = key, save = save, restore = restore }
+end
+
+-- Collect every provider's data and write the sidecar for `path`.
+function M.write(path)
+ local data = {}
+ for _, p in ipairs(M.providers) do
+ data[p.key] = p.save()
+ end
+ local f = io.open(sidecar_path(path), "w")
+ if f then
+ f:write(vim.json.encode(data))
+ f:close()
+ end
+end
+
+-- Read `path`'s sidecar and dispatch each provider's restore. A missing or malformed sidecar is
+-- silently ignored (sessions predating a provider simply won't have its key).
+function M.read(path)
+ local f = io.open(sidecar_path(path), "r")
+ if not f then
+ return
+ end
+ local content = f:read("*a")
+ f:close()
+ local ok, data = pcall(vim.json.decode, content)
+ if not (ok and type(data) == "table") then
+ return
+ end
+ for _, p in ipairs(M.providers) do
+ if data[p.key] ~= nil then
+ p.restore(data[p.key])
+ end
+ end
+end
+
+-- Delete the sidecar paired with `path`, if present.
+function M.remove(path)
+ local sidecar = sidecar_path(path)
+ if vim.uv.fs_stat(sidecar) then
+ vim.fs.rm(sidecar)
+ end
+end
+
+return M