Skip to content

Commit

Permalink
feat: can specify session dir in API calls
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc-stripe committed Sep 11, 2022
1 parent 84e89c0 commit 0ad0ec7
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 55 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ A: While it's amazing that this feature is built-in to vim, and it does an impre
- [ ] documentation
- [ ] make filepaths relative so sessions are portable
- [ ] extensions can add supported buffers (e.g. nvim-tree, aerial)
- [ ] can pass `dir` in to save/load/list
- [ ] quickfix

## Requirements
Expand Down
14 changes: 12 additions & 2 deletions lua/resession/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ local default_config = {
windows = {},
-- The name of the directory to store sessions in
dir = "session",
-- List of extensions
extensions = {},
-- Configuration for extensions
extensions = {
quickfix = {},
},
}

local autosave_timer
M.setup = function(config)
local resession = require("resession")
local util = require("resession.util")
local newconf = vim.tbl_deep_extend("force", default_config, config)

if newconf.options.save_all then
Expand All @@ -51,6 +54,13 @@ M.setup = function(config)
M[k] = v
end

for ext_name, ext_config in pairs(M.extensions) do
local ext = util.get_extension(ext_name)
if ext and ext.config then
ext.config(ext_config)
end
end

if autosave_timer then
autosave_timer:close()
autosave_timer = nil
Expand Down
90 changes: 42 additions & 48 deletions lua/resession/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ M.detach = function()
current_session = nil
end

---@class resession.ListOpts
---@field dir nil|string Name of directory to save to (overrides config.dir)

---@params opts nil|resession.ListOpts
---@return string[]
M.list = function()
M.list = function(opts)
opts = opts or {}
local config = require("resession.config")
local files = require("resession.files")
local util = require("resession.util")
local session_dir = util.get_session_dir()
local session_dir = util.get_session_dir(opts.dir)
if not files.exists(session_dir) then
return {}
end
Expand All @@ -54,7 +59,13 @@ M.list = function()
return ret
end

M.delete = function(name)
---@class resession.DeleteOpts
---@field dir nil|string Name of directory to save to (overrides config.dir)

---@param name string
---@param opts nil|resession.DeleteOpts
M.delete = function(name, opts)
opts = opts or {}
local files = require("resession.files")
local util = require("resession.util")
if not name then
Expand All @@ -70,7 +81,7 @@ M.delete = function(name)
end)
return
end
local filename = util.get_session_file(name)
local filename = util.get_session_file(name, opts.dir)
if not files.delete_file(filename) then
error(string.format("No session '%s'", filename))
end
Expand All @@ -79,38 +90,10 @@ M.delete = function(name)
end
end

local function extension_save(name)
local has_ext, ext = pcall(require, string.format("resession.extensions.%s", name))
if not has_ext then
vim.notify(string.format("[resession] Missing extension '%s'", name), vim.log.levels.WARN)
return
end
local ok, data = pcall(ext.on_save)
if ok then
return data
else
vim.notify(
string.format("[resession] Extension %s error: %s", name, data),
vim.log.levels.ERROR
)
end
end

local function extension_load(name, data)
local has_ext, ext = pcall(require, string.format("resession.extensions.%s", name))
if not has_ext then
vim.notify(string.format("[resession] Missing extension '%s'", name), vim.log.levels.WARN)
return
end
local ok, err = pcall(ext.on_load, data)
if not ok then
vim.notify(string.format("[resession] Extension %s error: %s", name, err), vim.log.levels.ERROR)
end
end

---@class resession.SaveOpts
---@field detach nil|boolean Immediately detach from the saved session
---@field notify nil|boolean Notify on success
---@field dir nil|string Name of directory to save to (overrides config.dir)

---@param name? string
---@param opts? resession.SaveOpts
Expand All @@ -133,7 +116,7 @@ M.save = function(name, opts)
local files = require("resession.files")
local layout = require("resession.layout")
local util = require("resession.util")
local filename = util.get_session_file(name)
local filename = util.get_session_file(name, opts.dir)
local data = {
buffers = {},
tabs = {},
Expand Down Expand Up @@ -165,17 +148,18 @@ M.save = function(name, opts)
tab.wins = layout.add_win_info_to_layout(tabnr, winlayout)
end

for _, ext_name in ipairs(config.extensions) do
if data[ext_name] then
vim.notify(
string.format(
"[resession] Cannot run extension named '%s'; it conflicts with built-in data",
ext_name
),
vim.log.levels.WARN
)
else
data[ext_name] = extension_save(ext_name)
for ext_name in pairs(config.extensions) do
local ext = util.get_extension(ext_name)
if ext then
local ok, ext_data = pcall(ext.on_save)
if ok then
vim.notify(
string.format("[resession] Extension %s save error: %s", ext_name, ext_data),
vim.log.levels.ERROR
)
else
data[ext_name] = ext_data
end
end
end

Expand Down Expand Up @@ -220,6 +204,7 @@ end
---@field detach nil|boolean Detach from session after loading
---@field reset nil|boolean Close everthing before loading the session (default true)
---@field silence_errors nil|boolean Don't error when trying to load a missing session
---@field dir nil|string Name of directory to load from (overrides config.dir)

---@param name? string
---@param opts? resession.LoadOpts
Expand All @@ -244,7 +229,7 @@ M.load = function(name, opts)
end)
return
end
local filename = util.get_session_file(name)
local filename = util.get_session_file(name, opts.dir)
local data = files.load_json_file(filename)
if not data then
if not opts.silence_errors then
Expand Down Expand Up @@ -290,9 +275,18 @@ M.load = function(name, opts)
vim.api.nvim_set_current_win(curwin)
end

for _, ext_name in ipairs(config.extensions) do
for ext_name in pairs(config.extensions) do
if data[ext_name] then
extension_load(ext_name, data[ext_name])
local ext = util.get_extension(ext_name)
if ext then
local ok, err = pcall(ext.on_load, data)
if not ok then
vim.notify(
string.format("[resession] Extension %s load error: %s", ext_name, err),
vim.log.levels.ERROR
)
end
end
end
end

Expand Down
21 changes: 17 additions & 4 deletions lua/resession/util.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
local config = require("resession.config")
local M = {}

---@param name
---@return resession.Extension
M.get_extension = function(name)
local has_ext, ext = pcall(require, string.format("resession.extensions.%s", name))
if has_ext then
return ext
else
vim.notify_once(string.format("[resession] Missing extension '%s'", name), vim.log.levels.WARN)
end
end

---@return table<string, any>
M.save_global_options = function()
local ret = {}
Expand Down Expand Up @@ -71,18 +82,20 @@ M.restore_buf_options = function(bufnr, opts)
end
end

---@param dirname? string
---@return string
M.get_session_dir = function()
M.get_session_dir = function(dirname)
local files = require("resession.files")
return files.get_stdpath_filename("data", config.dir)
return files.get_stdpath_filename("data", dirname or config.dir)
end

---@param name string The name of the session
---@param dirname? string
---@return string
M.get_session_file = function(name)
M.get_session_file = function(name, dirname)
local files = require("resession.files")
local filename = string.format("%s.json", name:gsub(files.sep, "_"))
return files.join(M.get_session_dir(), filename)
return files.join(M.get_session_dir(dirname), filename)
end

return M

0 comments on commit 0ad0ec7

Please sign in to comment.