-
-
Notifications
You must be signed in to change notification settings - Fork 634
feat: experiment: restore nvim-tree on session load, see https://github.com/nvim-tree/nvim-tree.lua/issues/3343 #3335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d5bbe20
feat: restore buffers after loading a session
igorlfs 3cddd18
feat(sessions): invalid json handling
igorlfs afad151
feat(sessions): switch to "persist in a file" strategy
igorlfs 018cf9a
docs: no longer needs to toggle sessionoptions flag
igorlfs f06e5e3
Merge branch 'master' into session-restore
alex-courtis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| local notify = require("nvim-tree.notify") | ||
|
|
||
| local M = {} | ||
|
|
||
| local storepath = vim.fn.stdpath("data") .. "/nvim-tree-session.json" | ||
|
|
||
| local function decode_session_file() | ||
| local file = io.open(storepath, "r") | ||
|
|
||
| if file then | ||
| local content = file:read("*all") | ||
| file:close() | ||
| if content and content ~= "" then | ||
| return vim.json.decode(content) | ||
| end | ||
| end | ||
| -- Notifying on failure could be noisy, as it'd happen if the file simply did not exist | ||
| end | ||
|
|
||
| local function write_session_file(session_file_content) | ||
| local file, errmsg = io.open(storepath, "w") | ||
|
|
||
| if file then | ||
| file:write(vim.json.encode(session_file_content)) | ||
| file:close() | ||
| else | ||
| notify.warn(string.format("Invalid session file (%s): %s", storepath, errmsg)) | ||
| end | ||
| end | ||
|
|
||
| function M.save() | ||
| -- We either always save the session data, which ends up populating the storepath with empty data | ||
| -- Or we gate by the tree's visibility, which could create "out of sync" scenario: | ||
| -- if the tree is initially open and the session is saved, it won't be overridden later, | ||
| -- if the tree is no longer visible. However, when restoring, this is harmless. | ||
| if require("nvim-tree.api").tree.is_visible({ any_tabpage = true }) then | ||
| local ok, session_file_content = pcall(decode_session_file) | ||
|
|
||
| if not ok then | ||
| notify.warn(string.format("Failed to decode session file (%s): %s", storepath, session_file_content)) | ||
| return | ||
| end | ||
|
|
||
| -- might be nil at this point | ||
| session_file_content = session_file_content or {} | ||
|
|
||
| local cwd = require("nvim-tree.core").get_cwd() | ||
|
|
||
| session_file_content[vim.v.this_session] = { cwd = cwd } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like using the session path as a key - minimise any ambiguities. Test: Multiple sessions in one file are correctly loaded and the correct session is updated. |
||
|
|
||
| local ok2, err = pcall(write_session_file, session_file_content) | ||
|
|
||
| if not ok2 then | ||
| notify.warn(string.format("Failed to write session file (%s): %s", storepath, err)) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| function M.restore() | ||
| local api = require("nvim-tree.api").tree | ||
|
|
||
| ---@type table<integer,boolean> | ||
| local tabs = {} | ||
|
|
||
| local ok, session_file_content = pcall(decode_session_file) | ||
|
|
||
| -- Failing to restore cwd is not fatal, we can continue | ||
| if not ok then | ||
| notify.warn(string.format("Failed to decode session file (%s): %s", storepath, session_file_content)) | ||
| end | ||
|
|
||
| local path = session_file_content and session_file_content[vim.v.this_session] and session_file_content[vim.v.this_session].cwd or nil | ||
|
|
||
| -- Save tabs with leftover nvim-tree buffers | ||
| for _, tab in ipairs(vim.api.nvim_list_tabpages()) do | ||
| for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tab)) do | ||
| local buf = vim.api.nvim_win_get_buf(win) | ||
| if api.is_tree_buf(buf) then | ||
| tabs[tab] = true | ||
| end | ||
| end | ||
| end | ||
|
|
||
| -- The new window may inherit options from the current one if we don't schedule | ||
| vim.schedule(function() | ||
| api.close_in_all_tabs() | ||
|
|
||
| for tab, _ in pairs(tabs) do | ||
| if vim.api.nvim_tabpage_is_valid(tab) then | ||
| local win = vim.api.nvim_tabpage_get_win(tab) | ||
|
|
||
| -- Invoke `open` from each tab's current window to prevent having to switch tabs | ||
| if vim.api.nvim_win_is_valid(win) then | ||
| vim.api.nvim_win_call(win, function() | ||
| api.open({ path = path }) | ||
| end) | ||
| end | ||
| end | ||
| end | ||
| end) | ||
| end | ||
|
|
||
| return M | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to work nicely; I only get messages once and sessions loaded correctly.
If we run into problems, say, execution on the first event is too early, we could use the debouncer instead, for delayed one-shot e.g.