stevearc / resession.nvim

A replacement for mksession with a better API
MIT License
175 stars 13 forks source link

feat!: `get_current()` returns custom session save directory if available #31

Closed Subjective closed 9 months ago

Subjective commented 9 months ago

Currently, there is no easy way (afaik) to retrieve session data for sessions not stored in the default save directory from within the session itself. It would be nice if the API exposed a function to do exactly that. One fairly clean way of doing this might be to add this functionality to the existing get_current(), by allowing it to have a second optional return string representing the save directory. This way, data for the current session can be retrieved (no matter the save directory) like this:

local resession = require "resession"
local files = require "resession.files"
local util = require "resession.util"

local filename = util.get_session_file(resession.get_current())
local data = files.load_json_file(filename)

If you're wondering what my use case is, I would like to have my Grapple tags specific to a session, and one way to do this by having a custom resolver that creates a scope based on the cwd of the current session. (Since projects.nvim autochanges the directory, it's necessary to have the scope resolved to global cwd stored by resession.nvim as opposed to the vim's cwd so that the tags don't get reset). This allows Grapple's builtin resession extension to function seamlessly in this kind of workflow.

Example Grapple setup ```lua local scope = require "grapple.scope" local resession = require "resession" local files = require "resession.files" local util = require "resession.util" local get_session_path = function(session_name, dirname) if session_name then local filename = util.get_session_file(session_name, dirname) local data = files.load_json_file(filename) if data then local session_cwd = data.tab_scoped and data.tabs[1].cwd or data.global.cwd return string.format("%s", session_cwd) end end end local session_path = scope.resolver(function() if resession.get_current() then return string.format("%s", get_session_path(resession.get_current())) end end, { cache = false, persist = false }) local resolver = scope.fallback { session_path, require("grapple.scope_resolvers").git, } local format_title = function() local current_session, session_dir = resession.get_current() if current_session then local title = string.format(" %s [%s] ", current_session, util.shorten_path(get_session_path(current_session, session_dir))) return #title > 50 and string.format(" %s ", current_session) or title else local git_root = require("grapple.state").ensure_loaded(require("grapple.scope_resolvers").git) return string.format(" %s ", git_root ~= vim.env.HOME and util.shorten_path(git_root) or git_root) end end resession.add_hook("pre_save", function() if require("resession").get_current() == nil then require("grapple").save() require("grapple.settings").integrations.resession = true end end) resession.add_hook("pre_load", function() require("grapple").save() require("grapple.settings").integrations.resession = true end) local unload_scopes = function() local grapple_state = require("grapple.state").state() for loaded_scope, _ in pairs(grapple_state) do if loaded_scope ~= get_session_path(resession.get_current()) then require("grapple.state").reset(loaded_scope, true) end end end resession.add_hook("post_save", function() unload_scopes() end) resession.add_hook("post_load", function() unload_scopes() end) ```
Subjective commented 9 months ago
Not sure why the generate script for docs formatted the return types like this: Type Desc
string ?, string?
stevearc commented 9 months ago

Looks good, thanks!