Compare commits

...

5 Commits

Author SHA1 Message Date
Alexander Courtis
c97f42044d Merge branch 'master' into 3323 2026-07-20 10:03:06 +10:00
Simon Barth
4213bd6eab style(#3223): change prompt of create file to "Create " (#3350) 2026-07-16 08:42:15 +10:00
Alexander Courtis
f2dd529e3f Merge branch 'master' into 3323 2026-07-10 11:34:55 +10:00
Igor Lacerda
cf18a662cd feat: experiment: restore nvim-tree on session load, see https://github.com/nvim-tree/nvim-tree.lua/issues/3343 (#3335)
* feat: restore buffers after loading a session

* feat(sessions): invalid json handling

* feat(sessions): switch to "persist in a file" strategy

* docs: no longer needs to toggle sessionoptions flag

---------

Co-authored-by: Alexander Courtis <alex@courtis.org>
2026-07-10 11:27:15 +10:00
Alexander Courtis
8f73cbb7d2 fix(#3323): experiment with removing window picker status line clearing, for vim._core.ui2 case 2026-05-01 09:46:12 +10:00
7 changed files with 144 additions and 3 deletions

View File

@@ -1911,6 +1911,11 @@ Config: experimental *nvim-tree-config-experimental*
In the event of a problem please disable the experiment and raise an
issue.
Fields: ~
• {session_restore_nvim}? (`boolean`, default: `false`) Restore
nvim-tree buffers when restoring vim sessions
(requires 0.13+).
==============================================================================
Config: log *nvim-tree-config-log*
@@ -2216,6 +2221,7 @@ Following is the default configuration, see |nvim_tree.config| for details. >lua
persist = false,
},
experimental = {
session_restore_nvim = false
},
log = {
enable = false,

View File

@@ -9,6 +9,9 @@ error("Cannot require a meta file")
---
---@class nvim_tree.config.experimental
---
---Restore nvim-tree buffers when restoring vim sessions (requires 0.13+).
---(default: `false`)
---@field session_restore_nvim? boolean
--Example below for future reference:
--
--Buffers opened by nvim-tree will use with relative paths instead of absolute.

View File

@@ -49,7 +49,7 @@ function M.fn(node)
local containing_folder = utils.path_add_trailing(dir.absolute_path)
local input_opts = {
prompt = "Create file ",
prompt = "Create ",
default = containing_folder,
completion = "file",
}

View File

@@ -1,5 +1,6 @@
-- Copyright 2019 Yazdani Kiyan under MIT License
local lib = require("nvim-tree.lib")
local log = require("nvim-tree.log")
local notify = require("nvim-tree.notify")
local utils = require("nvim-tree.utils")
local full_name = require("nvim-tree.renderer.components.full-name")
@@ -94,7 +95,12 @@ local function pick_win_id()
return not vim.tbl_contains(selectable, id)
end, win_ids)
if laststatus == 3 then
-- experiment only for #3323
local clear_not_selectable_statusline = false
log.line("dev", "clear_unselectable_statusline=%s", clear_not_selectable_statusline)
if clear_not_selectable_statusline then
for _, win_id in ipairs(not_selectable) do
local ok_status, statusline = pcall(vim.api.nvim_get_option_value, "statusline", { win = win_id })
@@ -144,7 +150,7 @@ local function pick_win_id()
end
end
if laststatus == 3 then
if clear_not_selectable_statusline then
for _, id in ipairs(not_selectable) do
-- Ensure window still exists at this point
if vim.api.nvim_win_is_valid(id) then

View File

@@ -17,6 +17,28 @@ function M.global()
end,
})
if vim.fn.has("nvim-0.13") == 1 and config.g.experimental.session_restore_nvim then
vim.api.nvim_create_autocmd("SessionWritePre", { ---@diagnostic disable-line: param-type-mismatch
group = augroup_id,
callback = function()
-- We must schedule to wait until `vim.v.this_session` is properly updated
-- This prevents overwriting the data if a new session is created with a new `:mksession`
vim.schedule(require("nvim-tree.session").save)
end,
})
vim.api.nvim_create_autocmd("SessionLoadPost", {
group = augroup_id,
-- Workaround: this event fires multiple times (report upstream),
-- failure notifications could show up many times.
once = true,
callback = function()
require("nvim-tree.session").restore()
end,
})
end
if config.g.tab.sync.open then
vim.api.nvim_create_autocmd("TabEnter", {
group = augroup_id,

View File

@@ -297,6 +297,7 @@ M.d = { -- config-default-start
persist = false,
},
experimental = {
session_restore_nvim = false
},
log = {
enable = false,

103
lua/nvim-tree/session.lua Normal file
View File

@@ -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 }
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