From 30a26acd651a5bea37f247ed8e9718e948f1280b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 12:16:21 +1100 Subject: [PATCH 01/27] perf(#3257): remove remove-file setup --- lua/nvim-tree/actions/fs/init.lua | 1 - lua/nvim-tree/actions/fs/remove-file.lua | 25 ++++++++++-------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/lua/nvim-tree/actions/fs/init.lua b/lua/nvim-tree/actions/fs/init.lua index b308a86a01e..f054848e793 100644 --- a/lua/nvim-tree/actions/fs/init.lua +++ b/lua/nvim-tree/actions/fs/init.lua @@ -6,7 +6,6 @@ M.rename_file = require("nvim-tree.actions.fs.rename-file") M.trash = require("nvim-tree.actions.fs.trash") function M.setup(opts) - M.remove_file.setup(opts) M.rename_file.setup(opts) M.trash.setup(opts) end diff --git a/lua/nvim-tree/actions/fs/remove-file.lua b/lua/nvim-tree/actions/fs/remove-file.lua index e818f0709bc..4db5ab4fa89 100644 --- a/lua/nvim-tree/actions/fs/remove-file.lua +++ b/lua/nvim-tree/actions/fs/remove-file.lua @@ -4,6 +4,7 @@ local events = require("nvim-tree.events") local view = require("nvim-tree.view") local lib = require("nvim-tree.lib") local notify = require("nvim-tree.notify") +local config = require("nvim-tree.config") local DirectoryLinkNode = require("nvim-tree.node.directory-link") local DirectoryNode = require("nvim-tree.node.directory") @@ -51,7 +52,7 @@ local function clear_buffer(absolute_path) if not view.View.float.quit_on_focus_loss then vim.api.nvim_set_current_win(tree_winnr) end - if M.config.actions.remove_file.close_window then + if config.g.actions.remove_file.close_window then close_windows(buf.windows) end return @@ -141,18 +142,18 @@ local function remove_one(node) notify.info(notify.render_path(node.absolute_path) .. " was properly removed.") end local explorer = core.get_explorer() - if not M.config.filesystem_watchers.enable and explorer then + if not config.g.filesystem_watchers.enable and explorer then explorer:reload_explorer() end end - if M.config.ui.confirm.remove then + if config.g.ui.confirm.remove then local prompt_select = "Remove " .. node.name .. "?" - local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, M.config.ui.confirm.default_yes) + local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, config.g.ui.confirm.default_yes) lib.prompt(prompt_input, prompt_select, items_short, items_long, "nvimtree_remove", function(item_short) utils.clear_prompt() - if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then + if item_short == "y" or item_short == (config.g.ui.confirm.default_yes and "") then do_remove() end end) @@ -181,18 +182,18 @@ local function remove_many(nodes) notify.info(string.format("%d nodes properly removed.", removed)) end local explorer = core.get_explorer() - if not M.config.filesystem_watchers.enable and explorer then + if not config.g.filesystem_watchers.enable and explorer then explorer:reload_explorer() end end - if M.config.ui.confirm.remove then + if config.g.ui.confirm.remove then local prompt_select = string.format("Remove %d selected?", #nodes) - local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, M.config.ui.confirm.default_yes) + local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, config.g.ui.confirm.default_yes) lib.prompt(prompt_input, prompt_select, items_short, items_long, "nvimtree_remove", function(item_short) utils.clear_prompt() - if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then + if item_short == "y" or item_short == (config.g.ui.confirm.default_yes and "") then execute() end end) @@ -210,10 +211,4 @@ function M.fn(node_or_nodes) end end -function M.setup(opts) - M.config.ui = opts.ui - M.config.actions = opts.actions - M.config.filesystem_watchers = opts.filesystem_watchers -end - return M From 85d3291eb9a6ab5d2810ebcb3602f0041aa163e1 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 12:17:54 +1100 Subject: [PATCH 02/27] perf(#3257): remove rename-file setup --- lua/nvim-tree/actions/fs/init.lua | 1 - lua/nvim-tree/actions/fs/rename-file.lua | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/nvim-tree/actions/fs/init.lua b/lua/nvim-tree/actions/fs/init.lua index f054848e793..1389f3094fb 100644 --- a/lua/nvim-tree/actions/fs/init.lua +++ b/lua/nvim-tree/actions/fs/init.lua @@ -6,7 +6,6 @@ M.rename_file = require("nvim-tree.actions.fs.rename-file") M.trash = require("nvim-tree.actions.fs.trash") function M.setup(opts) - M.rename_file.setup(opts) M.trash.setup(opts) end diff --git a/lua/nvim-tree/actions/fs/rename-file.lua b/lua/nvim-tree/actions/fs/rename-file.lua index ee1c4857984..ffad7b14c94 100644 --- a/lua/nvim-tree/actions/fs/rename-file.lua +++ b/lua/nvim-tree/actions/fs/rename-file.lua @@ -2,6 +2,7 @@ local core = require("nvim-tree.core") local utils = require("nvim-tree.utils") local events = require("nvim-tree.events") local notify = require("nvim-tree.notify") +local config = require("nvim-tree.config") local find_file = require("nvim-tree.actions.finders.find-file").fn @@ -163,7 +164,7 @@ local function prompt_to_rename(node, modifier) local full_new_path = prepend .. new_file_path .. append M.rename(node, full_new_path) - if not M.config.filesystem_watchers.enable then + if not config.g.filesystem_watchers.enable then explorer:reload_explorer() end @@ -192,7 +193,7 @@ function M.rename_full(node) end function M.setup(opts) - M.config.filesystem_watchers = opts.filesystem_watchers + config.g.filesystem_watchers = opts.filesystem_watchers end return M From 426e272defaadf8a76681a6f064e16e1b773e2a6 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 12:19:38 +1100 Subject: [PATCH 03/27] perf(#3257): remove trash setup --- lua/nvim-tree/actions/fs/init.lua | 4 ---- lua/nvim-tree/actions/fs/trash.lua | 29 ++++++++++++----------------- lua/nvim-tree/actions/init.lua | 1 - 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/lua/nvim-tree/actions/fs/init.lua b/lua/nvim-tree/actions/fs/init.lua index 1389f3094fb..07db7b95881 100644 --- a/lua/nvim-tree/actions/fs/init.lua +++ b/lua/nvim-tree/actions/fs/init.lua @@ -5,8 +5,4 @@ M.remove_file = require("nvim-tree.actions.fs.remove-file") M.rename_file = require("nvim-tree.actions.fs.rename-file") M.trash = require("nvim-tree.actions.fs.trash") -function M.setup(opts) - M.trash.setup(opts) -end - return M diff --git a/lua/nvim-tree/actions/fs/trash.lua b/lua/nvim-tree/actions/fs/trash.lua index ba038e8cf1c..5b73e99f28f 100644 --- a/lua/nvim-tree/actions/fs/trash.lua +++ b/lua/nvim-tree/actions/fs/trash.lua @@ -3,6 +3,7 @@ local lib = require("nvim-tree.lib") local notify = require("nvim-tree.notify") local utils = require("nvim-tree.utils") local events = require("nvim-tree.events") +local config = require("nvim-tree.config") local DirectoryLinkNode = require("nvim-tree.node.directory-link") local DirectoryNode = require("nvim-tree.node.directory") @@ -32,9 +33,9 @@ end ---@param node Node function M.remove(node) - local binary = M.config.trash.cmd:gsub(" .*$", "") + local binary = config.g.trash.cmd:gsub(" .*$", "") if vim.fn.executable(binary) == 0 then - notify.warn(string.format("trash.cmd '%s' is not an executable.", M.config.trash.cmd)) + notify.warn(string.format("trash.cmd '%s' is not an executable.", config.g.trash.cmd)) return end @@ -46,7 +47,7 @@ function M.remove(node) -- trashes a path (file or folder) local function trash_path(on_exit) local need_sync_wait = utils.is_windows - local job = vim.fn.jobstart(M.config.trash.cmd .. " " .. vim.fn.shellescape(node.absolute_path), { + local job = vim.fn.jobstart(config.g.trash.cmd .. " " .. vim.fn.shellescape(node.absolute_path), { detach = not need_sync_wait, on_exit = on_exit, on_stderr = on_stderr, @@ -65,7 +66,7 @@ function M.remove(node) return end events._dispatch_folder_removed(node.absolute_path) - if not M.config.filesystem_watchers.enable and explorer then + if not config.g.filesystem_watchers.enable and explorer then explorer:reload_explorer() end end) @@ -78,7 +79,7 @@ function M.remove(node) end events._dispatch_file_removed(node.absolute_path) clear_buffer(node.absolute_path) - if not M.config.filesystem_watchers.enable and explorer then + if not config.g.filesystem_watchers.enable and explorer then explorer:reload_explorer() end end) @@ -96,13 +97,13 @@ local function trash_one(node) M.remove(node) end - if M.config.ui.confirm.trash then + if config.g.ui.confirm.trash then local prompt_select = "Trash " .. node.name .. "?" - local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, M.config.ui.confirm.default_yes) + local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, config.g.ui.confirm.default_yes) lib.prompt(prompt_input, prompt_select, items_short, items_long, "nvimtree_trash", function(item_short) utils.clear_prompt() - if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then + if item_short == "y" or item_short == (config.g.ui.confirm.default_yes and "") then do_trash() end end) @@ -128,13 +129,13 @@ local function trash_many(nodes) end end - if M.config.ui.confirm.trash then + if config.g.ui.confirm.trash then local prompt_select = string.format("Trash %d selected?", #nodes) - local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, M.config.ui.confirm.default_yes) + local prompt_input, items_short, items_long = utils.confirm_prompt(prompt_select, config.g.ui.confirm.default_yes) lib.prompt(prompt_input, prompt_select, items_short, items_long, "nvimtree_trash", function(item_short) utils.clear_prompt() - if item_short == "y" or item_short == (M.config.ui.confirm.default_yes and "") then + if item_short == "y" or item_short == (config.g.ui.confirm.default_yes and "") then execute() end end) @@ -152,10 +153,4 @@ function M.fn(node_or_nodes) end end -function M.setup(opts) - M.config.ui = opts.ui - M.config.trash = opts.trash - M.config.filesystem_watchers = opts.filesystem_watchers -end - return M diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index d117a24119a..cbfe1fe2d16 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -7,7 +7,6 @@ M.node = require("nvim-tree.actions.node") M.tree = require("nvim-tree.actions.tree") function M.setup(opts) - M.fs.setup(opts) M.node.setup(opts) M.tree.setup(opts) end From c14dca35f5d025347ed03d582aed046debf36c50 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 12:22:52 +1100 Subject: [PATCH 04/27] perf(#3257): remove actions.fs init --- lua/nvim-tree/actions/fs/init.lua | 8 -------- lua/nvim-tree/actions/init.lua | 1 - lua/nvim-tree/api/impl.lua | 16 ++++++++-------- 3 files changed, 8 insertions(+), 17 deletions(-) delete mode 100644 lua/nvim-tree/actions/fs/init.lua diff --git a/lua/nvim-tree/actions/fs/init.lua b/lua/nvim-tree/actions/fs/init.lua deleted file mode 100644 index 07db7b95881..00000000000 --- a/lua/nvim-tree/actions/fs/init.lua +++ /dev/null @@ -1,8 +0,0 @@ -local M = {} - -M.create_file = require("nvim-tree.actions.fs.create-file") -M.remove_file = require("nvim-tree.actions.fs.remove-file") -M.rename_file = require("nvim-tree.actions.fs.rename-file") -M.trash = require("nvim-tree.actions.fs.trash") - -return M diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index cbfe1fe2d16..1a3b9aa7469 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -1,7 +1,6 @@ local M = {} M.finders = require("nvim-tree.actions.finders") -M.fs = require("nvim-tree.actions.fs") M.moves = require("nvim-tree.actions.moves") M.node = require("nvim-tree.actions.node") M.tree = require("nvim-tree.actions.tree") diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 217e3e854ca..2839d6e6618 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -155,17 +155,17 @@ function M.hydrate_post_setup(api) api.fs.copy.filename = en(function(e, n) e.clipboard:copy_filename(n) end) api.fs.copy.node = ev(function(e, n) e.clipboard:copy(n) end) api.fs.copy.relative_path = en(function(e, n) e.clipboard:copy_path(n) end) - api.fs.create = _n(function(n) require("nvim-tree.actions").fs.create_file.fn(n) end) + api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) api.fs.paste = en(function(e, n) e.clipboard:paste(n) end) api.fs.print_clipboard = e_(function(e) e.clipboard:print_clipboard() end) - api.fs.remove = _v(function(n) require("nvim-tree.actions").fs.remove_file.fn(n) end) - api.fs.rename = _n(function(n) require("nvim-tree.actions").fs.rename_file.rename_node(n) end) - api.fs.rename_basename = _n(function(n) require("nvim-tree.actions").fs.rename_file.rename_basename(n) end) - api.fs.rename_full = _n(function(n) require("nvim-tree.actions").fs.rename_file.rename_full(n) end) - api.fs.rename_node = _n(function(n) require("nvim-tree.actions").fs.rename_file.rename_node(n) end) - api.fs.rename_sub = _n(function(n) require("nvim-tree.actions").fs.rename_file.rename_sub(n) end) - api.fs.trash = _v(function(n) require("nvim-tree.actions").fs.trash.fn(n) end) + api.fs.remove = _v(function(n) require("nvim-tree.actions.fs.remove-file").fn(n) end) + api.fs.rename = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_node(n) end) + api.fs.rename_basename = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_basename(n) end) + api.fs.rename_full = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_full(n) end) + api.fs.rename_node = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_node(n) end) + api.fs.rename_sub = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_sub(n) end) + api.fs.trash = _v(function(n) require("nvim-tree.actions.fs.trash").fn(n) end) api.git.reload = e_(function(e) e:reload_git() end) From 0b6a1a5e9a5408d249fd4d0ddc87582ef290c982 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 12:24:56 +1100 Subject: [PATCH 05/27] perf(#3257): remove file-popup setup --- lua/nvim-tree/actions/node/file-popup.lua | 7 ++----- lua/nvim-tree/actions/node/init.lua | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/actions/node/file-popup.lua b/lua/nvim-tree/actions/node/file-popup.lua index fb6d022af6e..cec98280008 100644 --- a/lua/nvim-tree/actions/node/file-popup.lua +++ b/lua/nvim-tree/actions/node/file-popup.lua @@ -1,4 +1,5 @@ local utils = require("nvim-tree.utils") +local config = require("nvim-tree.config") local M = {} @@ -38,7 +39,7 @@ local function setup_window(node) local max_width = vim.fn.max(vim.tbl_map(function(n) return #n end, lines)) - local open_win_config = vim.tbl_extend("force", M.open_win_config, { + local open_win_config = vim.tbl_extend("force", config.g.actions.file_popup.open_win_config, { width = max_width + 1, height = #lines, noautocmd = true, @@ -89,8 +90,4 @@ function M.toggle_file_info(node) }) end -function M.setup(opts) - M.open_win_config = opts.actions.file_popup.open_win_config -end - return M diff --git a/lua/nvim-tree/actions/node/init.lua b/lua/nvim-tree/actions/node/init.lua index f7075959b5e..e0c9c6a2713 100644 --- a/lua/nvim-tree/actions/node/init.lua +++ b/lua/nvim-tree/actions/node/init.lua @@ -8,7 +8,6 @@ M.buffer = require("nvim-tree.actions.node.buffer") function M.setup(opts) require("nvim-tree.actions.node.system-open").setup(opts) - require("nvim-tree.actions.node.file-popup").setup(opts) require("nvim-tree.actions.node.open-file").setup(opts) end From 364035b9c5e2cdae6941cd87fdf927e39202e110 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 12:37:40 +1100 Subject: [PATCH 06/27] perf(#3257): remove open-file setup --- lua/nvim-tree/actions/node/init.lua | 1 - lua/nvim-tree/actions/node/open-file.lua | 53 ++++++++++-------------- lua/nvim-tree/config.lua | 12 ++++++ 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/lua/nvim-tree/actions/node/init.lua b/lua/nvim-tree/actions/node/init.lua index e0c9c6a2713..b2f6e979d18 100644 --- a/lua/nvim-tree/actions/node/init.lua +++ b/lua/nvim-tree/actions/node/init.lua @@ -8,7 +8,6 @@ M.buffer = require("nvim-tree.actions.node.buffer") function M.setup(opts) require("nvim-tree.actions.node.system-open").setup(opts) - require("nvim-tree.actions.node.open-file").setup(opts) end return M diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 984a732e20e..259bfabe569 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -4,6 +4,7 @@ local notify = require("nvim-tree.notify") local utils = require("nvim-tree.utils") local full_name = require("nvim-tree.renderer.components.full-name") local view = require("nvim-tree.view") +local config = require("nvim-tree.config") local DirectoryNode = require("nvim-tree.node.directory") local FileLinkNode = require("nvim-tree.node.file-link") @@ -36,7 +37,7 @@ local function usable_win_ids() return vim.tbl_filter(function(id) local bufid = vim.api.nvim_win_get_buf(id) - for option, v in pairs(M.window_picker.exclude) do + for option, v in pairs(config.g.actions.open_file.window_picker.exclude) do local ok, option_value if vim.fn.has("nvim-0.10") == 1 then ok, option_value = pcall(vim.api.nvim_get_option_value, option, { buf = bufid }) @@ -74,8 +75,8 @@ local function pick_win_id() return selectable[1] end - if #M.window_picker.chars < #selectable then - notify.error(string.format("More windows (%d) than actions.open_file.window_picker.chars (%d).", #selectable, #M.window_picker.chars)) + if #config.g.actions.open_file.window_picker.chars < #selectable then + notify.error(string.format("More windows (%d) than actions.open_file.window_picker.chars (%d).", #selectable, #config.g.actions.open_file.window_picker.chars)) return nil end @@ -126,7 +127,7 @@ local function pick_win_id() -- Setup UI for _, id in ipairs(selectable) do - local char = M.window_picker.chars:sub(i, i) + local char = config.g.actions.open_file.window_picker.chars:sub(i, i) local ok_status, statusline, ok_hl, winhl if vim.fn.has("nvim-0.10") == 1 then @@ -152,7 +153,7 @@ local function pick_win_id() end i = i + 1 - if i > #M.window_picker.chars then + if i > #config.g.actions.open_file.window_picker.chars then break end end @@ -194,7 +195,7 @@ local function pick_win_id() vim.o.laststatus = laststatus vim.opt.fillchars = fillchars - if not vim.tbl_contains(vim.split(M.window_picker.chars, ""), resp) then + if not vim.tbl_contains(vim.split(config.g.actions.open_file.window_picker.chars, ""), resp) then return end @@ -202,10 +203,10 @@ local function pick_win_id() end local function open_file_in_tab(filename) - if M.quit_on_open then + if config.g.actions.open_file.quit_on_open then view.close() end - if M.relative_path then + if config.g.actions.open_file.relative_path then filename = utils.path_relative(filename, vim.fn.getcwd()) end vim.cmd.tabnew() @@ -220,20 +221,20 @@ local function open_file_in_tab(filename) end local function drop(filename) - if M.quit_on_open then + if config.g.actions.open_file.quit_on_open then view.close() end - if M.relative_path then + if config.g.actions.open_file.relative_path then filename = utils.path_relative(filename, vim.fn.getcwd()) end vim.cmd("drop " .. vim.fn.fnameescape(filename)) end local function tab_drop(filename) - if M.quit_on_open then + if config.g.actions.open_file.quit_on_open then view.close() end - if M.relative_path then + if config.g.actions.open_file.relative_path then filename = utils.path_relative(filename, vim.fn.getcwd()) end vim.cmd("tab :drop " .. vim.fn.fnameescape(filename)) @@ -257,7 +258,7 @@ end local function get_target_winid(mode) local target_winid - if not M.window_picker.enable or string.find(mode, "no_picker") then + if not config.g.actions.open_file.window_picker.enable or string.find(mode, "no_picker") then target_winid = lib.target_winid local usable_wins = usable_win_ids() -- first available usable window @@ -270,8 +271,8 @@ local function get_target_winid(mode) end else -- pick a window - if type(M.window_picker.picker) == "function" then - target_winid = M.window_picker.picker() + if type(config.g.actions.open_file.window_picker.picker) == "function" then + target_winid = config.g.actions.open_file.window_picker.picker() else target_winid = pick_win_id() end @@ -315,9 +316,9 @@ local function open_in_new_window(filename, mode) -- non-floating, non-nvim-tree windows local win_ids = vim.tbl_filter(function(id) - local config = vim.api.nvim_win_get_config(id) + local win_config = vim.api.nvim_win_get_config(id) local bufnr = vim.api.nvim_win_get_buf(id) - return config and config.relative == "" or utils.is_nvim_tree_buf(bufnr) + return win_config and win_config.relative == "" or utils.is_nvim_tree_buf(bufnr) end, vim.api.nvim_list_wins()) local create_new_window = #win_ids == 1 -- This implies that the nvim-tree window is the only one @@ -363,7 +364,7 @@ local function open_in_new_window(filename, mode) end local fname - if M.relative_path then + if config.g.actions.open_file.relative_path then fname = utils.escape_special_chars(vim.fn.fnameescape(utils.path_relative(filename, vim.fn.getcwd()))) else fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) @@ -394,7 +395,7 @@ end local function edit_in_current_buf(filename) require("nvim-tree.view").abandon_current_window() - if M.relative_path then + if config.g.actions.open_file.relative_path then filename = utils.path_relative(filename, vim.fn.getcwd()) end vim.cmd("keepalt keepjumps edit " .. vim.fn.fnameescape(filename)) @@ -438,7 +439,7 @@ function M.fn(mode, filename) vim.bo.bufhidden = "" end - if M.resize_window then + if config.g.actions.open_file.resize_window then view.resize() end @@ -446,7 +447,7 @@ function M.fn(mode, filename) return on_preview(buf_loaded) end - if M.quit_on_open then + if config.g.actions.open_file.quit_on_open then view.close() end end @@ -564,14 +565,4 @@ function M.tab(node) open_or_expand_or_dir_up(node, "tabnew") end -function M.setup(opts) - M.quit_on_open = opts.actions.open_file.quit_on_open - M.resize_window = opts.actions.open_file.resize_window - M.relative_path = opts.actions.open_file.relative_path - if opts.actions.open_file.window_picker.chars then - opts.actions.open_file.window_picker.chars = tostring(opts.actions.open_file.window_picker.chars):upper() - end - M.window_picker = opts.actions.open_file.window_picker -end - return M diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 5b1211ccf43..83af294cf46 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -488,6 +488,16 @@ local function validate_config(u) end end +---Normalise the (user) config +---@param u nvim_tree.config +local function process_config(u) + + ---Always use upper case for window pickers + if u.actions.open_file.window_picker.chars then + u.actions.open_file.window_picker.chars = tostring(u.actions.open_file.window_picker.chars):upper() + end +end + ---Validate user config and migrate legacy. ---Merge with M.d and persist as M.g ---When no user config M.g is set to M.d and M.u is set to nil @@ -509,6 +519,8 @@ function M.setup(u) validate_config(u) + process_config(u) + -- set global to the validated and populated user config M.g = vim.tbl_deep_extend("force", M.d, u) end From 6bb2d7f239f737dacb42fea1ae8b124d7d8a4b3b Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:25:43 +1100 Subject: [PATCH 07/27] perf(#3257): remove system-open setup --- lua/nvim-tree/actions/init.lua | 1 - lua/nvim-tree/actions/node/init.lua | 4 -- lua/nvim-tree/actions/node/system-open.lua | 50 ++++++++++------------ lua/nvim-tree/config.lua | 28 +++++++----- 4 files changed, 41 insertions(+), 42 deletions(-) diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index 1a3b9aa7469..89a8e38b44c 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -6,7 +6,6 @@ M.node = require("nvim-tree.actions.node") M.tree = require("nvim-tree.actions.tree") function M.setup(opts) - M.node.setup(opts) M.tree.setup(opts) end diff --git a/lua/nvim-tree/actions/node/init.lua b/lua/nvim-tree/actions/node/init.lua index b2f6e979d18..5f91ce5d045 100644 --- a/lua/nvim-tree/actions/node/init.lua +++ b/lua/nvim-tree/actions/node/init.lua @@ -6,8 +6,4 @@ M.run_command = require("nvim-tree.actions.node.run-command") M.system_open = require("nvim-tree.actions.node.system-open") M.buffer = require("nvim-tree.actions.node.buffer") -function M.setup(opts) - require("nvim-tree.actions.node.system-open").setup(opts) -end - return M diff --git a/lua/nvim-tree/actions/node/system-open.lua b/lua/nvim-tree/actions/node/system-open.lua index 9cc11c492fe..4c7b260c31f 100644 --- a/lua/nvim-tree/actions/node/system-open.lua +++ b/lua/nvim-tree/actions/node/system-open.lua @@ -1,18 +1,33 @@ local notify = require("nvim-tree.notify") local utils = require("nvim-tree.utils") +local config = require("nvim-tree.config") local M = {} ---@param node Node local function user(node) - if #M.config.system_open.cmd == 0 then - require("nvim-tree.utils").notify.warn("Cannot open file with system application. Unrecognized platform.") + local cmd = config.g.system_open.cmd + local args = config.g.system_open.args + + if #cmd == 0 then + if utils.is_windows then + cmd = "cmd" + args = { "/c", "start", '""' } + elseif utils.is_macos then + cmd = "open" + elseif utils.is_unix then + cmd = "xdg-open" + end + end + + if #cmd == 0 then + notify.warn("Cannot open file with system application. Unrecognized platform.") return end local process = { - cmd = M.config.system_open.cmd, - args = M.config.system_open.args, + cmd = cmd, + args = args, errors = "\n", stderr = vim.loop.new_pipe(false), } @@ -61,30 +76,11 @@ end ---@param node Node function M.fn(node) - M.open(node) -end - --- TODO #2430 always use native once 0.10 is the minimum neovim version -function M.setup(opts) - M.config = {} - M.config.system_open = opts.system_open or {} - - if vim.fn.has("nvim-0.10") == 1 and #M.config.system_open.cmd == 0 then - M.open = native + -- TODO #2430 always use native once 0.10 is the minimum neovim version + if vim.fn.has("nvim-0.19") == 1 and #config.g.system_open.cmd == 0 then + native(node) else - M.open = user - if #M.config.system_open.cmd == 0 then - if utils.is_windows then - M.config.system_open = { - cmd = "cmd", - args = { "/c", "start", '""' }, - } - elseif utils.is_macos then - M.config.system_open.cmd = "open" - elseif utils.is_unix then - M.config.system_open.cmd = "xdg-open" - end - end + user(node) end end diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 83af294cf46..fb2fd23f196 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -304,14 +304,6 @@ M.d = { -- config-default-start }, } -- config-default-end --- Immediately apply OS specific localisations to defaults -if utils.is_macos or utils.is_windows then - M.d.trash.cmd = "trash" -end -if utils.is_windows then - M.d.filesystem_watchers.max_events = 1000 -end - local FIELD_SKIP_VALIDATE = { open_win_config = true, } @@ -488,11 +480,24 @@ local function validate_config(u) end end +---Localise the (default) config with OS specifics +---@param d nvim_tree.config +local function localise_config(d) + -- Trash + if utils.is_macos or utils.is_windows then + d.trash.cmd = "trash" + end + + -- Watchers + if utils.is_windows then + d.filesystem_watchers.max_events = 1000 + end +end + ---Normalise the (user) config ---@param u nvim_tree.config local function process_config(u) - - ---Always use upper case for window pickers + -- Open if u.actions.open_file.window_picker.chars then u.actions.open_file.window_picker.chars = tostring(u.actions.open_file.window_picker.chars):upper() end @@ -543,4 +548,7 @@ function M.g_clone() return vim.deepcopy(M.g) end +---Immediately localise the defaults once and once only +localise_config(M.d) + return M From e416f4bedb58e551d4ef37a2e3d3c4af43859911 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:28:32 +1100 Subject: [PATCH 08/27] perf(#3257): remove open-file setup --- lua/nvim-tree/actions/node/open-file.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 259bfabe569..53a1b015c78 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -76,7 +76,8 @@ local function pick_win_id() end if #config.g.actions.open_file.window_picker.chars < #selectable then - notify.error(string.format("More windows (%d) than actions.open_file.window_picker.chars (%d).", #selectable, #config.g.actions.open_file.window_picker.chars)) + notify.error(string.format("More windows (%d) than actions.open_file.window_picker.chars (%d).", #selectable, + #config.g.actions.open_file.window_picker.chars)) return nil end From 730682a0ec2b9689dbceb8faa1a76ebd8d6ebf4e Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:33:21 +1100 Subject: [PATCH 09/27] perf(#3257): remove actions.node init --- lua/nvim-tree/actions/init.lua | 1 - lua/nvim-tree/actions/node/init.lua | 9 -------- lua/nvim-tree/api/impl.lua | 36 ++++++++++++++--------------- 3 files changed, 18 insertions(+), 28 deletions(-) delete mode 100644 lua/nvim-tree/actions/node/init.lua diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index 89a8e38b44c..dc3090d115e 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -2,7 +2,6 @@ local M = {} M.finders = require("nvim-tree.actions.finders") M.moves = require("nvim-tree.actions.moves") -M.node = require("nvim-tree.actions.node") M.tree = require("nvim-tree.actions.tree") function M.setup(opts) diff --git a/lua/nvim-tree/actions/node/init.lua b/lua/nvim-tree/actions/node/init.lua deleted file mode 100644 index 5f91ce5d045..00000000000 --- a/lua/nvim-tree/actions/node/init.lua +++ /dev/null @@ -1,9 +0,0 @@ -local M = {} - -M.file_popup = require("nvim-tree.actions.node.file-popup") -M.open_file = require("nvim-tree.actions.node.open-file") -M.run_command = require("nvim-tree.actions.node.run-command") -M.system_open = require("nvim-tree.actions.node.system-open") -M.buffer = require("nvim-tree.actions.node.buffer") - -return M diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 2839d6e6618..29170c1108b 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -182,8 +182,8 @@ function M.hydrate_post_setup(api) api.marks.navigate.select = e_(function(e) e.marks:navigate_select() end) api.marks.toggle = ev(function(e, n) e.marks:toggle(n) end) - api.node.buffer.delete = _n(function(n, opts) require("nvim-tree.actions").node.buffer.delete(n, opts) end) - api.node.buffer.wipe = _n(function(n, opts) require("nvim-tree.actions").node.buffer.wipe(n, opts) end) + api.node.buffer.delete = _n(function(n, opts) require("nvim-tree.actions.node.buffer").delete(n, opts) end) + api.node.buffer.wipe = _n(function(n, opts) require("nvim-tree.actions.node.buffer").wipe(n, opts) end) api.node.collapse = _n(function(n, opts) require("nvim-tree.actions").tree.collapse.node(n, opts) end) api.node.expand = en(function(e, n, opts) e:expand_node(n, opts) end) api.node.navigate.diagnostics.next = __(function() require("nvim-tree.actions").moves.item.diagnostics_next() end) @@ -204,22 +204,22 @@ function M.hydrate_post_setup(api) api.node.navigate.sibling.last = _n(function(n) require("nvim-tree.actions").moves.sibling.last(n) end) api.node.navigate.sibling.next = _n(function(n) require("nvim-tree.actions").moves.sibling.next(n) end) api.node.navigate.sibling.prev = _n(function(n) require("nvim-tree.actions").moves.sibling.prev(n) end) - api.node.open.drop = _n(function(n) require("nvim-tree.actions").node.open_file.drop(n) end) - api.node.open.edit = _n(function(n) require("nvim-tree.actions").node.open_file.edit(n) end) - api.node.open.horizontal = _n(function(n) require("nvim-tree.actions").node.open_file.horizontal(n) end) - api.node.open.horizontal_no_picker = _n(function(n) require("nvim-tree.actions").node.open_file.horizontal_no_picker(n) end) - api.node.open.no_window_picker = _n(function(n) require("nvim-tree.actions").node.open_file.no_window_picker(n) end) - api.node.open.preview = _n(function(n) require("nvim-tree.actions").node.open_file.preview(n) end) - api.node.open.preview_no_picker = _n(function(n) require("nvim-tree.actions").node.open_file.preview_no_picker(n) end) - api.node.open.replace_tree_buffer = _n(function(n) require("nvim-tree.actions").node.open_file.replace_tree_buffer(n) end) - api.node.open.tab = _n(function(n) require("nvim-tree.actions").node.open_file.tab(n) end) - api.node.open.tab_drop = _n(function(n) require("nvim-tree.actions").node.open_file.tab_drop(n) end) - api.node.open.toggle_group_empty = _n(function(n) require("nvim-tree.actions").node.open_file.toggle_group_empty(n) end) - api.node.open.vertical = _n(function(n) require("nvim-tree.actions").node.open_file.vertical(n) end) - api.node.open.vertical_no_picker = _n(function(n) require("nvim-tree.actions").node.open_file.vertical_no_picker(n) end) - api.node.run.cmd = _n(function(n) require("nvim-tree.actions").node.run_command.run_file_command(n) end) - api.node.run.system = _n(function(n) require("nvim-tree.actions").node.system_open.fn(n) end) - api.node.show_info_popup = _n(function(n) require("nvim-tree.actions").node.file_popup.toggle_file_info(n) end) + api.node.open.drop = _n(function(n) require("nvim-tree.actions.node.open-file").drop(n) end) + api.node.open.edit = _n(function(n) require("nvim-tree.actions.node.open-file").edit(n) end) + api.node.open.horizontal = _n(function(n) require("nvim-tree.actions.node.open-file").horizontal(n) end) + api.node.open.horizontal_no_picker = _n(function(n) require("nvim-tree.actions.node.open-file").horizontal_no_picker(n) end) + api.node.open.no_window_picker = _n(function(n) require("nvim-tree.actions.node.open-file").no_window_picker(n) end) + api.node.open.preview = _n(function(n) require("nvim-tree.actions.node.open-file").preview(n) end) + api.node.open.preview_no_picker = _n(function(n) require("nvim-tree.actions.node.open-file").preview_no_picker(n) end) + api.node.open.replace_tree_buffer = _n(function(n) require("nvim-tree.actions.node.open-file").replace_tree_buffer(n) end) + api.node.open.tab = _n(function(n) require("nvim-tree.actions.node.open-file").tab(n) end) + api.node.open.tab_drop = _n(function(n) require("nvim-tree.actions.node.open-file").tab_drop(n) end) + api.node.open.toggle_group_empty = _n(function(n) require("nvim-tree.actions.node.open-file").toggle_group_empty(n) end) + api.node.open.vertical = _n(function(n) require("nvim-tree.actions.node.open-file").vertical(n) end) + api.node.open.vertical_no_picker = _n(function(n) require("nvim-tree.actions.node.open-file").vertical_no_picker(n) end) + api.node.run.cmd = _n(function(n) require("nvim-tree.actions.node.run-command").run_file_command(n) end) + api.node.run.system = _n(function(n) require("nvim-tree.actions.node.system-open").fn(n) end) + api.node.show_info_popup = _n(function(n) require("nvim-tree.actions.node.file-popup").toggle_file_info(n) end) api.tree.change_root = __(function(path) require("nvim-tree.actions").tree.change_dir.fn(path) end) api.tree.change_root_to_node = en(function(e, n) e:change_dir_to_node(n) end) From adc4c0225ad2c8e1f9d3a08813ad51dbf7e310f6 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:35:31 +1100 Subject: [PATCH 10/27] perf(#3257): remove change-dir setup --- lua/nvim-tree/actions/tree/change-dir.lua | 8 ++------ lua/nvim-tree/actions/tree/init.lua | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lua/nvim-tree/actions/tree/change-dir.lua b/lua/nvim-tree/actions/tree/change-dir.lua index 8bf2af7345c..b4b194b366b 100644 --- a/lua/nvim-tree/actions/tree/change-dir.lua +++ b/lua/nvim-tree/actions/tree/change-dir.lua @@ -1,4 +1,5 @@ local core = require("nvim-tree.core") +local config = require("nvim-tree.config") local find_file = require("nvim-tree.actions.tree.find-file") local M = {} @@ -10,14 +11,9 @@ function M.fn(name) explorer:change_dir(name) end - if M.config.update_focused_file.update_root.enable then + if config.g.update_focused_file.update_root.enable then find_file.fn() end end ----@param config nvim_tree.config -function M.setup(config) - M.config = config -end - return M diff --git a/lua/nvim-tree/actions/tree/init.lua b/lua/nvim-tree/actions/tree/init.lua index ca0733d7cb3..16cd8b766d3 100644 --- a/lua/nvim-tree/actions/tree/init.lua +++ b/lua/nvim-tree/actions/tree/init.lua @@ -8,7 +8,6 @@ M.toggle = require("nvim-tree.actions.tree.toggle") M.resize = require("nvim-tree.actions.tree.resize") function M.setup(opts) - M.change_dir.setup(opts) M.find_file.setup(opts) M.open.setup(opts) M.toggle.setup(opts) From 575ff6d871f98288c3bc770fa8b7ed1cca5f0839 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:36:44 +1100 Subject: [PATCH 11/27] perf(#3257): remove find-file setup --- lua/nvim-tree/actions/tree/find-file.lua | 7 ++----- lua/nvim-tree/actions/tree/init.lua | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/actions/tree/find-file.lua b/lua/nvim-tree/actions/tree/find-file.lua index 0290ce2e17f..d58c9cbfb51 100644 --- a/lua/nvim-tree/actions/tree/find-file.lua +++ b/lua/nvim-tree/actions/tree/find-file.lua @@ -1,6 +1,7 @@ local core = require("nvim-tree.core") local lib = require("nvim-tree.lib") local view = require("nvim-tree.view") +local config = require("nvim-tree.config") local finders_find_file = require("nvim-tree.actions.finders.find-file") local M = {} @@ -56,7 +57,7 @@ function M.fn(opts) end -- update root - if opts.update_root or M.config.update_focused_file.update_root.enable then + if opts.update_root or config.g.update_focused_file.update_root.enable then require("nvim-tree").change_root(path, bufnr) end @@ -64,8 +65,4 @@ function M.fn(opts) finders_find_file.fn(path) end -function M.setup(opts) - M.config = opts or {} -end - return M diff --git a/lua/nvim-tree/actions/tree/init.lua b/lua/nvim-tree/actions/tree/init.lua index 16cd8b766d3..6c0253c1995 100644 --- a/lua/nvim-tree/actions/tree/init.lua +++ b/lua/nvim-tree/actions/tree/init.lua @@ -8,7 +8,6 @@ M.toggle = require("nvim-tree.actions.tree.toggle") M.resize = require("nvim-tree.actions.tree.resize") function M.setup(opts) - M.find_file.setup(opts) M.open.setup(opts) M.toggle.setup(opts) M.resize.setup(opts) From fd410a09f931ea436601b017a420f57e64fd8b69 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:37:48 +1100 Subject: [PATCH 12/27] perf(#3257): remove open setup --- lua/nvim-tree/actions/tree/init.lua | 1 - lua/nvim-tree/actions/tree/open.lua | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/actions/tree/init.lua b/lua/nvim-tree/actions/tree/init.lua index 6c0253c1995..3f294b38792 100644 --- a/lua/nvim-tree/actions/tree/init.lua +++ b/lua/nvim-tree/actions/tree/init.lua @@ -8,7 +8,6 @@ M.toggle = require("nvim-tree.actions.tree.toggle") M.resize = require("nvim-tree.actions.tree.resize") function M.setup(opts) - M.open.setup(opts) M.toggle.setup(opts) M.resize.setup(opts) end diff --git a/lua/nvim-tree/actions/tree/open.lua b/lua/nvim-tree/actions/tree/open.lua index 8c559d8cb54..5244706a033 100644 --- a/lua/nvim-tree/actions/tree/open.lua +++ b/lua/nvim-tree/actions/tree/open.lua @@ -1,5 +1,6 @@ local lib = require("nvim-tree.lib") local view = require("nvim-tree.view") +local config = require("nvim-tree.config") local finders_find_file = require("nvim-tree.actions.finders.find-file") local M = {} @@ -37,7 +38,7 @@ function M.fn(opts) end -- find file - if M.config.update_focused_file.enable or opts.find_file then + if config.g.update_focused_file.enable or opts.find_file then -- update root if opts.update_root then require("nvim-tree").change_root(previous_path, previous_buf) @@ -48,8 +49,4 @@ function M.fn(opts) end end -function M.setup(opts) - M.config = opts or {} -end - return M From d3394d3c6353ece3d4d15b2d3d8ea1f1e3716fd8 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:38:32 +1100 Subject: [PATCH 13/27] perf(#3257): remove toggle setup --- lua/nvim-tree/actions/tree/init.lua | 1 - lua/nvim-tree/actions/tree/toggle.lua | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/nvim-tree/actions/tree/init.lua b/lua/nvim-tree/actions/tree/init.lua index 3f294b38792..dd5512d2613 100644 --- a/lua/nvim-tree/actions/tree/init.lua +++ b/lua/nvim-tree/actions/tree/init.lua @@ -8,7 +8,6 @@ M.toggle = require("nvim-tree.actions.tree.toggle") M.resize = require("nvim-tree.actions.tree.resize") function M.setup(opts) - M.toggle.setup(opts) M.resize.setup(opts) end diff --git a/lua/nvim-tree/actions/tree/toggle.lua b/lua/nvim-tree/actions/tree/toggle.lua index cb9e557838a..f38b0999d90 100644 --- a/lua/nvim-tree/actions/tree/toggle.lua +++ b/lua/nvim-tree/actions/tree/toggle.lua @@ -1,5 +1,6 @@ local lib = require("nvim-tree.lib") local view = require("nvim-tree.view") +local config = require("nvim-tree.config") local finders_find_file = require("nvim-tree.actions.finders.find-file") local M = {} @@ -52,7 +53,7 @@ function M.fn(opts, no_focus, cwd, bang) }) -- find file - if M.config.update_focused_file.enable or opts.find_file then + if config.g.update_focused_file.enable or opts.find_file then -- update root if opts.update_root then require("nvim-tree").change_root(previous_path, previous_buf) @@ -69,8 +70,4 @@ function M.fn(opts, no_focus, cwd, bang) end end -function M.setup(opts) - M.config = opts or {} -end - return M From 024579613d8eb8f439db3a039d865285b0559bc6 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:40:07 +1100 Subject: [PATCH 14/27] perf(#3257): remove resize setup --- lua/nvim-tree.lua | 1 - lua/nvim-tree/actions/init.lua | 4 ---- lua/nvim-tree/actions/tree/init.lua | 4 ---- lua/nvim-tree/actions/tree/resize.lua | 4 ---- 4 files changed, 13 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index dec52e85d42..1a606d76f1b 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -284,7 +284,6 @@ function M.setup(config_user) log.raw("config", "%s\n", vim.inspect(config.g)) end - require("nvim-tree.actions").setup(config.g) require("nvim-tree.appearance").setup() require("nvim-tree.explorer"):setup(config.g) require("nvim-tree.explorer.watch").setup(config.g) diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index dc3090d115e..fc6556c4230 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -4,8 +4,4 @@ M.finders = require("nvim-tree.actions.finders") M.moves = require("nvim-tree.actions.moves") M.tree = require("nvim-tree.actions.tree") -function M.setup(opts) - M.tree.setup(opts) -end - return M diff --git a/lua/nvim-tree/actions/tree/init.lua b/lua/nvim-tree/actions/tree/init.lua index dd5512d2613..0ce71f71a65 100644 --- a/lua/nvim-tree/actions/tree/init.lua +++ b/lua/nvim-tree/actions/tree/init.lua @@ -7,8 +7,4 @@ M.open = require("nvim-tree.actions.tree.open") M.toggle = require("nvim-tree.actions.tree.toggle") M.resize = require("nvim-tree.actions.tree.resize") -function M.setup(opts) - M.resize.setup(opts) -end - return M diff --git a/lua/nvim-tree/actions/tree/resize.lua b/lua/nvim-tree/actions/tree/resize.lua index 7498efdfcca..31fbd53306b 100644 --- a/lua/nvim-tree/actions/tree/resize.lua +++ b/lua/nvim-tree/actions/tree/resize.lua @@ -44,8 +44,4 @@ function M.fn(opts) end end -function M.setup(opts) - M.config = opts or {} -end - return M From 32c7594f6ad26e5948f88626c5f9baecf59556f9 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:42:22 +1100 Subject: [PATCH 15/27] perf(#3257): remove finders init --- lua/nvim-tree/actions/finders/init.lua | 6 ------ lua/nvim-tree/api/impl.lua | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 lua/nvim-tree/actions/finders/init.lua diff --git a/lua/nvim-tree/actions/finders/init.lua b/lua/nvim-tree/actions/finders/init.lua deleted file mode 100644 index 55ae5a9d156..00000000000 --- a/lua/nvim-tree/actions/finders/init.lua +++ /dev/null @@ -1,6 +0,0 @@ -local M = {} - -M.find_file = require("nvim-tree.actions.finders.find-file") -M.search_node = require("nvim-tree.actions.finders.search-node") - -return M diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 29170c1108b..db7bf5cc9db 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -239,7 +239,7 @@ function M.hydrate_post_setup(api) api.tree.reload = e_(function(e) e:reload_explorer() end) api.tree.reload_git = e_(function(e) e:reload_git() end) api.tree.resize = __(function(opts) require("nvim-tree.actions").tree.resize.fn(opts) end) - api.tree.search_node = __(function() require("nvim-tree.actions").finders.search_node.fn() end) + api.tree.search_node = __(function() require("nvim-tree.actions.finders.search-node").fn() end) api.tree.toggle = __(function(opts) require("nvim-tree.actions").tree.toggle.fn(opts) end) api.tree.toggle_help = __(function() require("nvim-tree.help").toggle() end) api.tree.winid = __(function(opts) return require("nvim-tree.view").winid(opts) end) From da10b226d841dfd3f07d9d1a7f3242c56ba7c33c Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 13:45:27 +1100 Subject: [PATCH 16/27] perf(#3257): remove moves init --- lua/nvim-tree/actions/init.lua | 2 -- lua/nvim-tree/actions/moves/init.lua | 7 ------ lua/nvim-tree/api/impl.lua | 36 ++++++++++++++-------------- 3 files changed, 18 insertions(+), 27 deletions(-) delete mode 100644 lua/nvim-tree/actions/moves/init.lua diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua index fc6556c4230..5b44219dabb 100644 --- a/lua/nvim-tree/actions/init.lua +++ b/lua/nvim-tree/actions/init.lua @@ -1,7 +1,5 @@ local M = {} -M.finders = require("nvim-tree.actions.finders") -M.moves = require("nvim-tree.actions.moves") M.tree = require("nvim-tree.actions.tree") return M diff --git a/lua/nvim-tree/actions/moves/init.lua b/lua/nvim-tree/actions/moves/init.lua deleted file mode 100644 index b1e5be74afe..00000000000 --- a/lua/nvim-tree/actions/moves/init.lua +++ /dev/null @@ -1,7 +0,0 @@ -local M = {} - -M.item = require("nvim-tree.actions.moves.item") -M.parent = require("nvim-tree.actions.moves.parent") -M.sibling = require("nvim-tree.actions.moves.sibling") - -return M diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index db7bf5cc9db..78131c9bebc 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -186,24 +186,24 @@ function M.hydrate_post_setup(api) api.node.buffer.wipe = _n(function(n, opts) require("nvim-tree.actions.node.buffer").wipe(n, opts) end) api.node.collapse = _n(function(n, opts) require("nvim-tree.actions").tree.collapse.node(n, opts) end) api.node.expand = en(function(e, n, opts) e:expand_node(n, opts) end) - api.node.navigate.diagnostics.next = __(function() require("nvim-tree.actions").moves.item.diagnostics_next() end) - api.node.navigate.diagnostics.next_recursive = __(function() require("nvim-tree.actions").moves.item.diagnostics_next_recursive() end) - api.node.navigate.diagnostics.prev = __(function() require("nvim-tree.actions").moves.item.diagnostics_prev() end) - api.node.navigate.diagnostics.prev_recursive = __(function() require("nvim-tree.actions").moves.item.diagnostics_prev_recursive() end) - api.node.navigate.git.next = __(function() require("nvim-tree.actions").moves.item.git_next() end) - api.node.navigate.git.next_recursive = __(function() require("nvim-tree.actions").moves.item.git_next_recursive() end) - api.node.navigate.git.next_skip_gitignored = __(function() require("nvim-tree.actions").moves.item.git_next_skip_gitignored() end) - api.node.navigate.git.prev = __(function() require("nvim-tree.actions").moves.item.git_prev() end) - api.node.navigate.git.prev_recursive = __(function() require("nvim-tree.actions").moves.item.git_prev_recursive() end) - api.node.navigate.git.prev_skip_gitignored = __(function() require("nvim-tree.actions").moves.item.git_prev_skip_gitignored() end) - api.node.navigate.opened.next = __(function() require("nvim-tree.actions").moves.item.opened_next() end) - api.node.navigate.opened.prev = __(function() require("nvim-tree.actions").moves.item.opened_prev() end) - api.node.navigate.parent = _n(function(n) require("nvim-tree.actions").moves.parent.move(n) end) - api.node.navigate.parent_close = _n(function(n) require("nvim-tree.actions").moves.parent.move_close(n) end) - api.node.navigate.sibling.first = _n(function(n) require("nvim-tree.actions").moves.sibling.first(n) end) - api.node.navigate.sibling.last = _n(function(n) require("nvim-tree.actions").moves.sibling.last(n) end) - api.node.navigate.sibling.next = _n(function(n) require("nvim-tree.actions").moves.sibling.next(n) end) - api.node.navigate.sibling.prev = _n(function(n) require("nvim-tree.actions").moves.sibling.prev(n) end) + api.node.navigate.diagnostics.next = __(function() require("nvim-tree.actions.moves.item").diagnostics_next() end) + api.node.navigate.diagnostics.next_recursive = __(function() require("nvim-tree.actions.moves.item").diagnostics_next_recursive() end) + api.node.navigate.diagnostics.prev = __(function() require("nvim-tree.actions.moves.item").diagnostics_prev() end) + api.node.navigate.diagnostics.prev_recursive = __(function() require("nvim-tree.actions.moves.item").diagnostics_prev_recursive() end) + api.node.navigate.git.next = __(function() require("nvim-tree.actions.moves.item").git_next() end) + api.node.navigate.git.next_recursive = __(function() require("nvim-tree.actions.moves.item").git_next_recursive() end) + api.node.navigate.git.next_skip_gitignored = __(function() require("nvim-tree.actions.moves.item").git_next_skip_gitignored() end) + api.node.navigate.git.prev = __(function() require("nvim-tree.actions.moves.item").git_prev() end) + api.node.navigate.git.prev_recursive = __(function() require("nvim-tree.actions.moves.item").git_prev_recursive() end) + api.node.navigate.git.prev_skip_gitignored = __(function() require("nvim-tree.actions.moves.item").git_prev_skip_gitignored() end) + api.node.navigate.opened.next = __(function() require("nvim-tree.actions.moves.item").opened_next() end) + api.node.navigate.opened.prev = __(function() require("nvim-tree.actions.moves.item").opened_prev() end) + api.node.navigate.parent = _n(function(n) require("nvim-tree.actions.moves.parent").move(n) end) + api.node.navigate.parent_close = _n(function(n) require("nvim-tree.actions.moves.parent").move_close(n) end) + api.node.navigate.sibling.first = _n(function(n) require("nvim-tree.actions.moves.sibling").first(n) end) + api.node.navigate.sibling.last = _n(function(n) require("nvim-tree.actions.moves.sibling").last(n) end) + api.node.navigate.sibling.next = _n(function(n) require("nvim-tree.actions.moves.sibling").next(n) end) + api.node.navigate.sibling.prev = _n(function(n) require("nvim-tree.actions.moves.sibling").prev(n) end) api.node.open.drop = _n(function(n) require("nvim-tree.actions.node.open-file").drop(n) end) api.node.open.edit = _n(function(n) require("nvim-tree.actions.node.open-file").edit(n) end) api.node.open.horizontal = _n(function(n) require("nvim-tree.actions.node.open-file").horizontal(n) end) From cbfd04784bc75e78015e94eb14509c1795e524c4 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 16:07:31 +1100 Subject: [PATCH 17/27] perf(#3257): remove tree init --- lua/nvim-tree.lua | 7 ++++--- lua/nvim-tree/actions/init.lua | 5 ----- lua/nvim-tree/actions/tree/init.lua | 10 ---------- lua/nvim-tree/api/impl.lua | 16 ++++++++-------- 4 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 lua/nvim-tree/actions/init.lua delete mode 100644 lua/nvim-tree/actions/tree/init.lua diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 1a606d76f1b..1417df4d00d 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -2,7 +2,8 @@ local api = require("nvim-tree.api") local log = require("nvim-tree.log") local view = require("nvim-tree.view") local utils = require("nvim-tree.utils") -local actions = require("nvim-tree.actions") +local find_file = require("nvim-tree.actions.tree.find-file") +local change_dir = require("nvim-tree.actions.tree.change-dir") local core = require("nvim-tree.core") local notify = require("nvim-tree.notify") local config = require("nvim-tree.config") @@ -169,7 +170,7 @@ local function setup_autocommands() if config.g.sync_root_with_cwd then create_nvim_tree_autocmd("DirChanged", { callback = function() - actions.tree.change_dir.fn(vim.loop.cwd()) + change_dir.fn(vim.loop.cwd()) end, }) end @@ -181,7 +182,7 @@ local function setup_autocommands() return end utils.debounce("BufEnter:find_file", config.g.view.debounce_delay, function() - actions.tree.find_file.fn() + find_file.fn() end) end, }) diff --git a/lua/nvim-tree/actions/init.lua b/lua/nvim-tree/actions/init.lua deleted file mode 100644 index 5b44219dabb..00000000000 --- a/lua/nvim-tree/actions/init.lua +++ /dev/null @@ -1,5 +0,0 @@ -local M = {} - -M.tree = require("nvim-tree.actions.tree") - -return M diff --git a/lua/nvim-tree/actions/tree/init.lua b/lua/nvim-tree/actions/tree/init.lua deleted file mode 100644 index 0ce71f71a65..00000000000 --- a/lua/nvim-tree/actions/tree/init.lua +++ /dev/null @@ -1,10 +0,0 @@ -local M = {} - -M.change_dir = require("nvim-tree.actions.tree.change-dir") -M.find_file = require("nvim-tree.actions.tree.find-file") -M.collapse = require("nvim-tree.actions.tree.collapse") -M.open = require("nvim-tree.actions.tree.open") -M.toggle = require("nvim-tree.actions.tree.toggle") -M.resize = require("nvim-tree.actions.tree.resize") - -return M diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 78131c9bebc..11304e75408 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -184,7 +184,7 @@ function M.hydrate_post_setup(api) api.node.buffer.delete = _n(function(n, opts) require("nvim-tree.actions.node.buffer").delete(n, opts) end) api.node.buffer.wipe = _n(function(n, opts) require("nvim-tree.actions.node.buffer").wipe(n, opts) end) - api.node.collapse = _n(function(n, opts) require("nvim-tree.actions").tree.collapse.node(n, opts) end) + api.node.collapse = _n(function(n, opts) require("nvim-tree.actions.tree.collapse").node(n, opts) end) api.node.expand = en(function(e, n, opts) e:expand_node(n, opts) end) api.node.navigate.diagnostics.next = __(function() require("nvim-tree.actions.moves.item").diagnostics_next() end) api.node.navigate.diagnostics.next_recursive = __(function() require("nvim-tree.actions.moves.item").diagnostics_next_recursive() end) @@ -221,26 +221,26 @@ function M.hydrate_post_setup(api) api.node.run.system = _n(function(n) require("nvim-tree.actions.node.system-open").fn(n) end) api.node.show_info_popup = _n(function(n) require("nvim-tree.actions.node.file-popup").toggle_file_info(n) end) - api.tree.change_root = __(function(path) require("nvim-tree.actions").tree.change_dir.fn(path) end) + api.tree.change_root = __(function(path) require("nvim-tree.actions.tree.change-dir").fn(path) end) api.tree.change_root_to_node = en(function(e, n) e:change_dir_to_node(n) end) api.tree.change_root_to_parent = en(function(e, n) e:dir_up(n) end) api.tree.close = __(function() require("nvim-tree.view").close() end) api.tree.close_in_all_tabs = __(function() require("nvim-tree.view").close_all_tabs() end) api.tree.close_in_this_tab = __(function() require("nvim-tree.view").close_this_tab_only() end) - api.tree.collapse_all = __(function(opts) require("nvim-tree.actions").tree.collapse.all(opts) end) + api.tree.collapse_all = __(function(opts) require("nvim-tree.actions.tree.collapse").all(opts) end) api.tree.expand_all = en(function(e, n, opts) e:expand_all(n, opts) end) - api.tree.find_file = __(function(opts) require("nvim-tree.actions").tree.find_file.fn(opts) end) - api.tree.focus = __(function(opts) require("nvim-tree.actions").tree.open.fn(opts) end) + api.tree.find_file = __(function(opts) require("nvim-tree.actions.tree.find_file").fn(opts) end) + api.tree.focus = __(function(opts) require("nvim-tree.actions.tree.open").fn(opts) end) api.tree.get_node_under_cursor = en(function(e) return e:get_node_at_cursor() end) api.tree.get_nodes = en(function(e) return e:get_nodes() end) api.tree.is_tree_buf = __(function(bufnr) return require("nvim-tree.utils").is_nvim_tree_buf(bufnr) end) api.tree.is_visible = __(function(opts) return require("nvim-tree.view").is_visible(opts) end) - api.tree.open = __(function(opts) require("nvim-tree.actions").tree.open.fn(opts) end) + api.tree.open = __(function(opts) require("nvim-tree.actions.tree.open").fn(opts) end) api.tree.reload = e_(function(e) e:reload_explorer() end) api.tree.reload_git = e_(function(e) e:reload_git() end) - api.tree.resize = __(function(opts) require("nvim-tree.actions").tree.resize.fn(opts) end) + api.tree.resize = __(function(opts) require("nvim-tree.actions.tree.resize").fn(opts) end) api.tree.search_node = __(function() require("nvim-tree.actions.finders.search-node").fn() end) - api.tree.toggle = __(function(opts) require("nvim-tree.actions").tree.toggle.fn(opts) end) + api.tree.toggle = __(function(opts) require("nvim-tree.actions.tree.toggle").fn(opts) end) api.tree.toggle_help = __(function() require("nvim-tree.help").toggle() end) api.tree.winid = __(function(opts) return require("nvim-tree.view").winid(opts) end) From 722dee2b6cf36ca703be3327b3a87926d227adc1 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 16:12:45 +1100 Subject: [PATCH 18/27] perf(#3257): remove explorer setup --- lua/nvim-tree.lua | 1 - lua/nvim-tree/explorer/init.lua | 19 +++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 1417df4d00d..426a62611a5 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -286,7 +286,6 @@ function M.setup(config_user) end require("nvim-tree.appearance").setup() - require("nvim-tree.explorer"):setup(config.g) require("nvim-tree.explorer.watch").setup(config.g) require("nvim-tree.view").setup(config.g) require("nvim-tree.renderer.components").setup(config.g) diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index fcfce4821ea..eb9b5f5d097 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -1,5 +1,6 @@ local appearance = require("nvim-tree.appearance") local buffers = require("nvim-tree.buffers") +local config = require("nvim-tree.config") local core = require("nvim-tree.core") local git = require("nvim-tree.git") local log = require("nvim-tree.log") @@ -25,8 +26,6 @@ local FileNode = require("nvim-tree.node.file") local FILTER_REASON = require("nvim-tree.enum").FILTER_REASON local find_file = require("nvim-tree.actions.finders.find-file") -local config - ---@class (exact) Explorer: RootNode ---@field uid_explorer number vim.loop.hrtime() at construction time ---@field opts table user options @@ -59,7 +58,7 @@ function Explorer:new(args) self.augroup_id = vim.api.nvim_create_augroup("NvimTree_Explorer_" .. self.uid_explorer, {}) self.open = true - self.opts = config + self.opts = config.g self.sorters = Sorter({ explorer = self }) @@ -300,7 +299,7 @@ function Explorer:reload(node, project) ) local single_child = node:single_child_directory() - if config.renderer.group_empty and node.parent and single_child then + if self.opts.renderer.group_empty and node.parent and single_child then node.group_next = single_child local ns = self:reload(single_child, project) node.nodes = ns or {} @@ -448,7 +447,7 @@ function Explorer:explore(node, project, parent) local is_root = not node.parent local single_child = node:single_child_directory() - if config.renderer.group_empty and not is_root and single_child then + if self.opts.renderer.group_empty and not is_root and single_child then local child_cwd = single_child.link_to or single_child.absolute_path local child_project = git.load_project(child_cwd) node.group_next = single_child @@ -755,14 +754,14 @@ end ---@return boolean function Explorer:prevent_cwd_change(foldername) local is_same_cwd = foldername == self.absolute_path - local is_restricted_above = config.actions.change_dir.restrict_above_cwd and foldername < vim.fn.getcwd(-1, -1) + local is_restricted_above = self.opts.actions.change_dir.restrict_above_cwd and foldername < vim.fn.getcwd(-1, -1) return is_same_cwd or is_restricted_above end ---@private ---@return boolean function Explorer:should_change_dir() - return config.actions.change_dir.enable and vim.tbl_isempty(vim.v.event) + return self.opts.actions.change_dir.enable and vim.tbl_isempty(vim.v.event) end ---@private @@ -782,7 +781,7 @@ function Explorer:force_dirchange(foldername, should_open_view, should_init) local valid_dir = vim.fn.isdirectory(foldername) == 1 -- prevent problems on non existing dirs if valid_dir then if self:should_change_dir() then - self:cd(config.actions.change_dir.global, foldername) + self:cd(self.opts.actions.change_dir.global, foldername) end if should_init ~= false then @@ -835,8 +834,4 @@ function Explorer:change_dir_to_node(node) end end -function Explorer:setup(opts) - config = opts -end - return Explorer From 05f7cbd29c06764e1eb2148bb508bd6806d7c701 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Tue, 24 Mar 2026 16:59:51 +1100 Subject: [PATCH 19/27] perf(#3257): view uses config.g --- lua/nvim-tree/actions/fs/remove-file.lua | 7 ++-- lua/nvim-tree/actions/node/open-file.lua | 4 +- lua/nvim-tree/explorer/live-filter.lua | 5 ++- lua/nvim-tree/view.lua | 48 ++++++++++-------------- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/lua/nvim-tree/actions/fs/remove-file.lua b/lua/nvim-tree/actions/fs/remove-file.lua index 4db5ab4fa89..2aa08770877 100644 --- a/lua/nvim-tree/actions/fs/remove-file.lua +++ b/lua/nvim-tree/actions/fs/remove-file.lua @@ -1,7 +1,6 @@ local core = require("nvim-tree.core") local utils = require("nvim-tree.utils") local events = require("nvim-tree.events") -local view = require("nvim-tree.view") local lib = require("nvim-tree.lib") local notify = require("nvim-tree.notify") local config = require("nvim-tree.config") @@ -19,7 +18,7 @@ local M = { local function close_windows(windows) -- When floating, prevent closing the last non-floating window. -- For details see #2503, #3187. - if view.View.float.enable then + if config.g.view.float.enable then local non_float_count = 0 for _, win in ipairs(vim.api.nvim_list_wins()) do if vim.api.nvim_win_get_config(win).relative == "" then @@ -44,12 +43,12 @@ local function clear_buffer(absolute_path) for _, buf in pairs(bufs) do if buf.name == absolute_path then local tree_winnr = vim.api.nvim_get_current_win() - if buf.hidden == 0 and (#bufs > 1 or view.View.float.enable) then + if buf.hidden == 0 and (#bufs > 1 or config.g.view.float.enable) then vim.api.nvim_set_current_win(buf.windows[1]) vim.cmd(":bn") end vim.api.nvim_buf_delete(buf.bufnr, { force = true }) - if not view.View.float.quit_on_focus_loss then + if not config.g.view.float.quit_on_focus_loss then vim.api.nvim_set_current_win(tree_winnr) end if config.g.actions.remove_file.close_window then diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 53a1b015c78..80dc1d1c41f 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -323,7 +323,7 @@ local function open_in_new_window(filename, mode) end, vim.api.nvim_list_wins()) local create_new_window = #win_ids == 1 -- This implies that the nvim-tree window is the only one - local new_window_side = (view.View.side == "right") and "aboveleft" or "belowright" + local new_window_side = (config.g.view.side == "right") and "aboveleft" or "belowright" -- Target is invalid: create new window if not vim.tbl_contains(win_ids, target_winid) then @@ -355,7 +355,7 @@ local function open_in_new_window(filename, mode) end end - if (mode == "preview" or mode == "preview_no_picker") and view.View.float.enable then + if (mode == "preview" or mode == "preview_no_picker") and config.g.view.float.enable then -- ignore "WinLeave" autocmd on preview -- because the registered "WinLeave" -- will kill the floating window immediately diff --git a/lua/nvim-tree/explorer/live-filter.lua b/lua/nvim-tree/explorer/live-filter.lua index 81e6da81657..3f2316690e9 100644 --- a/lua/nvim-tree/explorer/live-filter.lua +++ b/lua/nvim-tree/explorer/live-filter.lua @@ -1,5 +1,6 @@ local view = require("nvim-tree.view") local utils = require("nvim-tree.utils") +local config = require("nvim-tree.config") local Class = require("nvim-tree.classic") local Iterator = require("nvim-tree.iterators.node-iterator") @@ -56,7 +57,7 @@ local overlay_bufnr = 0 local overlay_winnr = 0 local function remove_overlay(self) - if view.View.float.enable and view.View.float.quit_on_focus_loss then + if config.g.view.float.enable and config.g.view.float.quit_on_focus_loss then -- return to normal nvim-tree float behaviour when filter window is closed vim.api.nvim_create_autocmd("WinLeave", { pattern = "NvimTree_*", @@ -166,7 +167,7 @@ local function calculate_overlay_win_width(self) end local function create_overlay(self) - if view.View.float.enable then + if config.g.view.float.enable then -- don't close nvim-tree float when focus is changed to filter window vim.api.nvim_clear_autocmds({ event = "WinLeave", diff --git a/lua/nvim-tree/view.lua b/lua/nvim-tree/view.lua index 638f52353b3..6e36c8e50da 100644 --- a/lua/nvim-tree/view.lua +++ b/lua/nvim-tree/view.lua @@ -2,6 +2,7 @@ local events = require("nvim-tree.events") local utils = require("nvim-tree.utils") local log = require("nvim-tree.log") local notify = require("nvim-tree.notify") +local config = require("nvim-tree.config") ---@class OpenInWinOpts ---@field hijack_current_buf boolean|nil default true @@ -18,15 +19,13 @@ local DEFAULT_LINES_EXCLUDED = { local DEFAULT_PADDING = 1 M.View = { - adaptive_size = false, - centralize_selection = false, - tabpages = {}, - cursors = {}, - hide_root_folder = false, - live_filter = { + adaptive_size = false, + tabpages = {}, + cursors = {}, + live_filter = { prev_focused_node = nil, }, - winopts = { + winopts = { relativenumber = false, number = false, list = false, @@ -178,17 +177,17 @@ local function set_window_options_and_buffer() end end ----@return table +---@return vim.api.keyset.win_config local function open_win_config() - if type(M.View.float.open_win_config) == "function" then - return M.View.float.open_win_config() + if type(config.g.view.float.open_win_config) == "function" then + return config.g.view.float.open_win_config() else - return M.View.float.open_win_config + return config.g.view.float.open_win_config --[[ @as vim.api.keyset.win_config ]] end end local function open_window() - if M.View.float.enable then + if config.g.view.float.enable then vim.api.nvim_open_win(0, true, open_win_config()) else vim.api.nvim_command("vsp") @@ -275,7 +274,7 @@ end ---@param tabpage integer|nil function M.close(tabpage) - if M.View.tab.sync.close then + if config.g.tab.sync.close then M.close_all_tabs() elseif tabpage then close(tabpage) @@ -348,7 +347,7 @@ end ---@param size string|number|nil function M.resize(size) - if M.View.float.enable and not M.View.adaptive_size then + if config.g.view.float.enable and not M.View.adaptive_size then -- if the floating windows's adaptive size is not desired, then the -- float size should be defined in view.float.open_win_config return @@ -370,7 +369,6 @@ function M.resize(size) if size then M.View.width = size - M.View.height = size end if not M.is_visible() then @@ -383,7 +381,7 @@ function M.resize(size) if new_size ~= vim.api.nvim_win_get_width(winnr) then vim.api.nvim_win_set_width(winnr, new_size) - if not M.View.preserve_window_proportions then + if not config.g.view.preserve_window_proportions then vim.cmd(":wincmd =") end end @@ -392,7 +390,7 @@ function M.resize(size) end function M.reposition_window() - local move_to = move_tbl[M.View.side] + local move_to = move_tbl[config.g.view.side] vim.api.nvim_command("wincmd " .. move_to) M.resize() end @@ -575,7 +573,7 @@ end ---@param cwd string|nil ---@return boolean function M.is_root_folder_visible(cwd) - return cwd ~= "/" and not M.View.hide_root_folder + return cwd ~= "/" and config.g.renderer.root_folder_label ~= false end -- used on ColorScheme event @@ -603,9 +601,9 @@ function M.configure_width(width) M.View.root_excluded = vim.tbl_contains(lines_excluded, "root") M.View.padding = width.padding or DEFAULT_PADDING elseif width == nil then - if M.config.width ~= nil then + if config.g.view.width ~= nil then -- if we had input config - fallback to it - M.configure_width(M.config.width) + M.configure_width(config.g.view.width) else -- otherwise - restore initial width M.View.width = M.View.initial_width @@ -616,23 +614,15 @@ function M.configure_width(width) end end +---@param opts nvim_tree.config function M.setup(opts) local options = opts.view or {} - M.View.centralize_selection = options.centralize_selection - M.View.side = (options.side == "right") and "right" or "left" - M.View.height = options.height - M.View.hide_root_folder = opts.renderer.root_folder_label == false - M.View.tab = opts.tab - M.View.preserve_window_proportions = options.preserve_window_proportions M.View.winopts.cursorline = options.cursorline M.View.winopts.cursorlineopt = options.cursorlineopt M.View.winopts.number = options.number M.View.winopts.relativenumber = options.relativenumber M.View.winopts.signcolumn = options.signcolumn - M.View.float = options.float - M.on_attach = opts.on_attach - M.config = options M.configure_width(options.width) M.View.initial_width = get_width() From 1784b985c3a079711290047ed5c525ffab4de98a Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Wed, 25 Mar 2026 15:12:41 +1100 Subject: [PATCH 20/27] perf(#3257): move os from utils to config, removing requires --- lua/nvim-tree/actions/fs/rename-file.lua | 2 +- lua/nvim-tree/actions/fs/trash.lua | 2 +- lua/nvim-tree/actions/node/system-open.lua | 7 ++-- lua/nvim-tree/config.lua | 38 ++++++++++++++-------- lua/nvim-tree/explorer/watch.lua | 3 +- lua/nvim-tree/utils.lua | 17 +++++----- lua/nvim-tree/watcher.lua | 4 +-- 7 files changed, 41 insertions(+), 32 deletions(-) diff --git a/lua/nvim-tree/actions/fs/rename-file.lua b/lua/nvim-tree/actions/fs/rename-file.lua index ffad7b14c94..0b4f22ac1d7 100644 --- a/lua/nvim-tree/actions/fs/rename-file.lua +++ b/lua/nvim-tree/actions/fs/rename-file.lua @@ -34,7 +34,7 @@ local function err_fmt(from, to, reason) end local function rename_file_exists(node, to) - if not utils.is_macos then + if not config.os.macos then return utils.file_exists(to) end diff --git a/lua/nvim-tree/actions/fs/trash.lua b/lua/nvim-tree/actions/fs/trash.lua index 5b73e99f28f..ef62a42e884 100644 --- a/lua/nvim-tree/actions/fs/trash.lua +++ b/lua/nvim-tree/actions/fs/trash.lua @@ -46,7 +46,7 @@ function M.remove(node) -- trashes a path (file or folder) local function trash_path(on_exit) - local need_sync_wait = utils.is_windows + local need_sync_wait = config.os.windows local job = vim.fn.jobstart(config.g.trash.cmd .. " " .. vim.fn.shellescape(node.absolute_path), { detach = not need_sync_wait, on_exit = on_exit, diff --git a/lua/nvim-tree/actions/node/system-open.lua b/lua/nvim-tree/actions/node/system-open.lua index 4c7b260c31f..be2b158cd67 100644 --- a/lua/nvim-tree/actions/node/system-open.lua +++ b/lua/nvim-tree/actions/node/system-open.lua @@ -1,5 +1,4 @@ local notify = require("nvim-tree.notify") -local utils = require("nvim-tree.utils") local config = require("nvim-tree.config") local M = {} @@ -10,12 +9,12 @@ local function user(node) local args = config.g.system_open.args if #cmd == 0 then - if utils.is_windows then + if config.os.windows then cmd = "cmd" args = { "/c", "start", '""' } - elseif utils.is_macos then + elseif config.os.macos then cmd = "open" - elseif utils.is_unix then + elseif config.os.unix then cmd = "xdg-open" end end diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index fb2fd23f196..131e8f18367 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -1,21 +1,31 @@ --This will be required after api, before setup. --This file should have minimal requires that are cheap and have no dependencies or are already required. -local notify = require("nvim-tree.notify") -local legacy = require("nvim-tree.legacy") -local utils = require("nvim-tree.utils") - --- short names like g are used rather than getters to keep code brief - +--Short names like g are used rather than getters to keep code brief local M = { - ---@type nvim_tree.config immutable default config + ---Immutable default config + ---@type nvim_tree.config d = {}, - ---@type nvim_tree.config? global current config, nil until setup called, mutable + ---Global current config, nil until setup called, mutable + ---@type nvim_tree.config? g = nil, - ---@type nvim_tree.config? immutable raw user config, nil when no user config passed to setup + ---Immutable raw user config, nil when no user config passed to setup + ---@type nvim_tree.config? u = nil, + + ---Immutable OS, detected once on first require + ---@type table<"unix"|"macos"|"wsl"|"windows", boolean> + os = nil +} + +M.os = { + unix = vim.fn.has("unix") == 1, + macos = vim.fn.has("mac") == 1 or vim.fn.has("macunix") == 1, + wsl = vim.fn.has("wsl") == 1, + -- false for WSL + windows = vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1, } M.d = { -- config-default-start @@ -476,7 +486,7 @@ local function validate_config(u) validate(u, M.d, ACCEPTED_STRINGS, ACCEPTED_TYPES, ACCEPTED_ENUMS, "") if msg then - notify.warn(msg .. "\n\nsee :help nvim-tree-config for available configuration options") + require("nvim-tree.notify").warn(msg .. "\n\nsee :help nvim-tree-config for available configuration options") end end @@ -484,12 +494,12 @@ end ---@param d nvim_tree.config local function localise_config(d) -- Trash - if utils.is_macos or utils.is_windows then + if M.os.macos or M.os.windows then d.trash.cmd = "trash" end -- Watchers - if utils.is_windows then + if M.os.windows then d.filesystem_watchers.max_events = 1000 end end @@ -510,7 +520,7 @@ end function M.setup(u) if not u or type(u) ~= "table" then if u then - notify.warn(string.format("invalid config type \"%s\" passed to setup, using defaults", type(u))) + require("nvim-tree.notify").warn(string.format("invalid config type \"%s\" passed to setup, using defaults", type(u))) end M.g = vim.deepcopy(M.d) M.u = nil @@ -520,7 +530,7 @@ function M.setup(u) -- retain user for reference M.u = vim.deepcopy(u) - legacy.migrate_config(u) + require("nvim-tree.legacy").migrate_config(u) validate_config(u) diff --git a/lua/nvim-tree/explorer/watch.lua b/lua/nvim-tree/explorer/watch.lua index 8641a291b39..442be4b91db 100644 --- a/lua/nvim-tree/explorer/watch.lua +++ b/lua/nvim-tree/explorer/watch.lua @@ -2,6 +2,7 @@ local log = require("nvim-tree.log") local git = require("nvim-tree.git") local utils = require("nvim-tree.utils") local notify = require("nvim-tree.notify") +local config = require("nvim-tree.config") local Watcher = require("nvim-tree.watcher").Watcher local M = { @@ -51,7 +52,7 @@ local function is_folder_ignored(path) ---@return boolean local function matches_dirs(p, dirs) for _, dir in ipairs(dirs) do - if utils.is_windows then + if config.os.windows then dir = dir:gsub("/", "\\\\") or dir end diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 32106d543e1..414d67d908e 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -1,10 +1,9 @@ +local config = require("nvim-tree.config") + local M = { debouncers = {}, } -M.is_unix = vim.fn.has("unix") == 1 -M.is_macos = vim.fn.has("mac") == 1 or vim.fn.has("macunix") == 1 -M.is_wsl = vim.fn.has("wsl") == 1 -- false for WSL M.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1 @@ -78,7 +77,7 @@ function M.path_relative(path, relative_to) end local norm_path = path - if M.is_windows then + if config.os.windows then norm_path = win_norm_path(norm_path) end @@ -187,13 +186,13 @@ function M.rename_loaded_buffers(old_path, new_path) end local is_windows_drive = function(path) - return (M.is_windows) and (path:match("^%a:\\$") ~= nil) + return (config.os.windows) and (path:match("^%a:\\$") ~= nil) end ---@param path string path to file or directory ---@return boolean function M.file_exists(path) - if not (M.is_windows or M.is_wsl) then + if not (config.os.windows or config.os.wsl) then local _, error = vim.loop.fs_stat(path) return error == nil end @@ -236,7 +235,7 @@ end ---@param path string ---@return string function M.canonical_path(path) - if M.is_windows and path:match("^%a:") then + if config.os.windows and path:match("^%a:") then return path:sub(1, 1):upper() .. path:sub(2) end return path @@ -257,7 +256,7 @@ function M.escape_special_chars(path) if path == nil then return path end - return M.is_windows and escape_special_char_for_windows(path) or path + return config.os.windows and escape_special_char_for_windows(path) or path end local function round(value) @@ -447,7 +446,7 @@ end ---@param absolute_path string ---@return boolean function M.is_executable(absolute_path) - if M.is_windows or M.is_wsl then + if config.os.windows or config.os.wsl then --- executable detection on windows is buggy and not performant hence it is disabled return false else diff --git a/lua/nvim-tree/watcher.lua b/lua/nvim-tree/watcher.lua index f188f6aece0..b29988538ab 100644 --- a/lua/nvim-tree/watcher.lua +++ b/lua/nvim-tree/watcher.lua @@ -89,7 +89,7 @@ function Event:start() end local message = string.format("File system watcher failed (%s) for path %s, halting watcher.", err, self.path) - if err == "EPERM" and (utils.is_windows or utils.is_wsl) then + if err == "EPERM" and (config.os.windows or config.os.wsl) then -- on directory removal windows will cascade the filesystem events out of order log.line("watcher", message) self:destroy() @@ -258,7 +258,7 @@ end ---@param path string ---@return boolean function M.is_fs_event_capable(path) - if not utils.is_windows then + if not config.os.windows then return true end From ff4b19075bb05489751a2daa9b8c4914e30650a7 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Wed, 25 Mar 2026 15:14:39 +1100 Subject: [PATCH 21/27] perf(#3257): move os from utils to config, removing requires --- lua/nvim-tree/config.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 131e8f18367..5f44f811287 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -4,11 +4,11 @@ --Short names like g are used rather than getters to keep code brief local M = { ---Immutable default config - ---@type nvim_tree.config + ---@type nvim_tree.config d = {}, ---Global current config, nil until setup called, mutable - ---@type nvim_tree.config? + ---@type nvim_tree.config? g = nil, ---Immutable raw user config, nil when no user config passed to setup From e5cb2a0d87e628e0a310cbcadf11d8e568fac38d Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 26 Mar 2026 10:51:00 +1100 Subject: [PATCH 22/27] perf(#3257): move os from utils to config, removing requires --- lua/nvim-tree/utils.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 414d67d908e..bb731f8ceb6 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -4,9 +4,6 @@ local M = { debouncers = {}, } --- false for WSL -M.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1 - ---@param haystack string ---@param needle string ---@return boolean From 697a42b751b5361dafb6b15131668dc558dada7e Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 26 Mar 2026 12:21:28 +1100 Subject: [PATCH 23/27] perf(#3257): remove watch setup --- lua/nvim-tree.lua | 1 - lua/nvim-tree/explorer/watch.lua | 45 ++++++++++++++------------------ 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 426a62611a5..75c5a32154c 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -286,7 +286,6 @@ function M.setup(config_user) end require("nvim-tree.appearance").setup() - require("nvim-tree.explorer.watch").setup(config.g) require("nvim-tree.view").setup(config.g) require("nvim-tree.renderer.components").setup(config.g) diff --git a/lua/nvim-tree/explorer/watch.lua b/lua/nvim-tree/explorer/watch.lua index 442be4b91db..a0884304f0e 100644 --- a/lua/nvim-tree/explorer/watch.lua +++ b/lua/nvim-tree/explorer/watch.lua @@ -5,10 +5,10 @@ local notify = require("nvim-tree.notify") local config = require("nvim-tree.config") local Watcher = require("nvim-tree.watcher").Watcher -local M = { - config = {}, - uid = 0, -} +local M = {} + +-- monotonically increasing, unique +local uid = 0 ---@param path string ---@return boolean @@ -48,7 +48,7 @@ local function is_folder_ignored(path) ---Return true when p matches an entry in dirs, escaping for windows ---@param p string absolute path - ---@param dirs string[] absolute or relative + ---@param dirs string[] regexes ---@return boolean local function matches_dirs(p, dirs) for _, dir in ipairs(dirs) do @@ -63,22 +63,22 @@ local function is_folder_ignored(path) return false end - if type(M.config.filesystem_watchers.ignore_dirs) == "table" then - if matches_dirs(path, M.config.filesystem_watchers.ignore_dirs) then + if type(config.g.filesystem_watchers.ignore_dirs) == "table" then + if matches_dirs(path, config.g.filesystem_watchers.ignore_dirs --[[@as string[] ]]) then return true end - elseif type(M.config.filesystem_watchers.ignore_dirs) == "function" then - if M.config.filesystem_watchers.ignore_dirs(path) then + elseif type(config.g.filesystem_watchers.ignore_dirs) == "function" then + if config.g.filesystem_watchers.ignore_dirs(path) then return true end end - if type(M.config.filesystem_watchers.whitelist_dirs) == "table" and #M.config.filesystem_watchers.whitelist_dirs > 0 then - if not matches_dirs(path, M.config.filesystem_watchers.whitelist_dirs) then + if type(config.g.filesystem_watchers.whitelist_dirs) == "table" and #config.g.filesystem_watchers.whitelist_dirs > 0 then + if not matches_dirs(path, config.g.filesystem_watchers.whitelist_dirs --[[@as string[] ]]) then return true end - elseif type(M.config.filesystem_watchers.whitelist_dirs) == "function" then - if not M.config.filesystem_watchers.whitelist_dirs(path) then + elseif type(config.g.filesystem_watchers.whitelist_dirs) == "function" then + if not config.g.filesystem_watchers.whitelist_dirs(path) then return true end end @@ -89,7 +89,7 @@ end ---@param node DirectoryNode ---@return Watcher|nil function M.create_watcher(node) - if not M.config.filesystem_watchers.enable or type(node) ~= "table" then + if not config.g.filesystem_watchers.enable or type(node) ~= "table" then return nil end @@ -106,18 +106,18 @@ function M.create_watcher(node) watcher.data.outstanding_events = watcher.data.outstanding_events + 1 -- disable watcher when outstanding exceeds max - if M.config.filesystem_watchers.max_events > 0 and watcher.data.outstanding_events > M.config.filesystem_watchers.max_events then + if config.g.filesystem_watchers.max_events > 0 and watcher.data.outstanding_events > config.g.filesystem_watchers.max_events then notify.error(string.format( "Observed %d consecutive file system events with interval < %dms, exceeding filesystem_watchers.max_events=%s. Disabling watcher for directory '%s'. Consider adding this directory to filesystem_watchers.ignore_dirs", watcher.data.outstanding_events, - M.config.filesystem_watchers.debounce_delay, - M.config.filesystem_watchers.max_events, + config.g.filesystem_watchers.debounce_delay, + config.g.filesystem_watchers.max_events, node.absolute_path )) node:destroy_watcher() end - utils.debounce(watcher.data.context, M.config.filesystem_watchers.debounce_delay, function() + utils.debounce(watcher.data.context, config.g.filesystem_watchers.debounce_delay, function() if watcher.destroyed then return end @@ -134,20 +134,15 @@ function M.create_watcher(node) end) end - M.uid = M.uid + 1 + uid = uid + 1 return Watcher:create({ path = path, callback = callback, data = { - context = "explorer:watch:" .. path .. ":" .. M.uid, + context = "explorer:watch:" .. path .. ":" .. uid, outstanding_events = 0, -- unprocessed events that have not been debounced } }) end -function M.setup(opts) - M.config.filesystem_watchers = opts.filesystem_watchers - M.uid = 0 -end - return M From 5d47b64dfc67be019a1c117cdfc36b58b8b14572 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 26 Mar 2026 12:42:57 +1100 Subject: [PATCH 24/27] perf(#3257): remove notify setup --- lua/nvim-tree.lua | 1 - lua/nvim-tree/notify.lua | 20 +++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 75c5a32154c..672718bf4ce 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -277,7 +277,6 @@ function M.setup(config_user) manage_netrw() - require("nvim-tree.notify").setup(config.g) require("nvim-tree.log").setup(config.g) if log.enabled("config") then diff --git a/lua/nvim-tree/notify.lua b/lua/nvim-tree/notify.lua index 7449960041f..c7a63ef9bef 100644 --- a/lua/nvim-tree/notify.lua +++ b/lua/nvim-tree/notify.lua @@ -1,9 +1,6 @@ -local M = {} +local config = require("nvim-tree.config") -local config = { - threshold = vim.log.levels.INFO, - absolute_path = true, -} +local M = {} local title_support ---@return boolean @@ -27,8 +24,11 @@ local modes = { } do + ---@param level vim.log.levels + ---@param msg string local dispatch = function(level, msg) - if level < config.threshold or not msg then + local threshold = config.g and config.g.notify.threshold or config.d.notify.threshold + if level < threshold or not msg then return end @@ -52,17 +52,11 @@ end ---@param path string ---@return string function M.render_path(path) - if config.absolute_path then + if config.g and config.g.notify.absolute_path then return path else return vim.fn.fnamemodify(path .. "/", ":h:t") end end -function M.setup(opts) - opts = opts or {} - config.threshold = opts.notify.threshold or vim.log.levels.INFO - config.absolute_path = opts.notify.absolute_path -end - return M From 857e13716672b294515f4a0b09002ce4edde1869 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 26 Mar 2026 15:34:51 +1100 Subject: [PATCH 25/27] perf(#3257): remove full-name setup --- lua/nvim-tree.lua | 4 ++++ lua/nvim-tree/renderer/components/full-name.lua | 13 +++++++------ lua/nvim-tree/renderer/components/init.lua | 2 -- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 672718bf4ce..f29005e5961 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -4,6 +4,7 @@ local view = require("nvim-tree.view") local utils = require("nvim-tree.utils") local find_file = require("nvim-tree.actions.tree.find-file") local change_dir = require("nvim-tree.actions.tree.change-dir") +local full_name = require("nvim-tree.renderer.components.full-name") local core = require("nvim-tree.core") local notify = require("nvim-tree.notify") local config = require("nvim-tree.config") @@ -249,6 +250,9 @@ local function setup_autocommands() end end, }) + + -- renderer.full name + full_name.setup_autocommands() end function M.purge_all_state() diff --git a/lua/nvim-tree/renderer/components/full-name.lua b/lua/nvim-tree/renderer/components/full-name.lua index 6c41f3909d9..adf5a4af6ad 100644 --- a/lua/nvim-tree/renderer/components/full-name.lua +++ b/lua/nvim-tree/renderer/components/full-name.lua @@ -1,3 +1,5 @@ +local config = require("nvim-tree.config") + local M = {} local utils = require("nvim-tree.utils") @@ -33,7 +35,7 @@ local function effective_win_width() return win_width - win_info[1].textoff end -local function show(opts) +local function show() local line_nr = vim.api.nvim_win_get_cursor(0)[1] if vim.wo.wrap then return @@ -96,15 +98,14 @@ local function show(opts) end end vim.cmd([[ setlocal nowrap noswapfile nobuflisted buftype=nofile bufhidden=wipe ]]) - if opts.view.cursorline then + if config.g.view.cursorline then vim.cmd([[ setlocal cursorline cursorlineopt=both ]]) end end) end -M.setup = function(opts) - M.config = opts.renderer - if not M.config.full_name then +function M.setup_autocommands() + if not config.g.renderer.full_name then return end @@ -124,7 +125,7 @@ M.setup = function(opts) pattern = { "NvimTree_*" }, callback = function() if utils.is_nvim_tree_buf(0) then - show(opts) + show() end end, }) diff --git a/lua/nvim-tree/renderer/components/init.lua b/lua/nvim-tree/renderer/components/init.lua index 748bf889497..a06827422dd 100644 --- a/lua/nvim-tree/renderer/components/init.lua +++ b/lua/nvim-tree/renderer/components/init.lua @@ -1,11 +1,9 @@ local M = {} -M.full_name = require("nvim-tree.renderer.components.full-name") M.devicons = require("nvim-tree.renderer.components.devicons") M.padding = require("nvim-tree.renderer.components.padding") function M.setup(opts) - M.full_name.setup(opts) M.devicons.setup(opts) M.padding.setup(opts) end From 862db0366beb7ff4c7738881dd8fe80ebfd6b92f Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 26 Mar 2026 15:47:04 +1100 Subject: [PATCH 26/27] perf(#3257): remove padding setup --- lua/nvim-tree/config.lua | 15 +++++ lua/nvim-tree/renderer/components/init.lua | 2 - lua/nvim-tree/renderer/components/padding.lua | 56 +++++++------------ 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 5f44f811287..44e54719236 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -511,6 +511,21 @@ local function process_config(u) if u.actions.open_file.window_picker.chars then u.actions.open_file.window_picker.chars = tostring(u.actions.open_file.window_picker.chars):upper() end + + -- Padding and Indent Markers + if u.renderer.indent_width < 1 then + u.renderer.indent_width = 1 + end + local function check_marker(symbol) + if #symbol == 0 then + return " " + end + -- return the first character from the UTF-8 encoded string; we may use utf8.codes from Lua 5.3 when available + return symbol:match("[%z\1-\127\194-\244][\128-\191]*") + end + for k, v in pairs(u.renderer.indent_markers.icons) do + u.renderer.indent_markers.icons[k] = check_marker(v) + end end ---Validate user config and migrate legacy. diff --git a/lua/nvim-tree/renderer/components/init.lua b/lua/nvim-tree/renderer/components/init.lua index a06827422dd..38e20432533 100644 --- a/lua/nvim-tree/renderer/components/init.lua +++ b/lua/nvim-tree/renderer/components/init.lua @@ -1,11 +1,9 @@ local M = {} M.devicons = require("nvim-tree.renderer.components.devicons") -M.padding = require("nvim-tree.renderer.components.padding") function M.setup(opts) M.devicons.setup(opts) - M.padding.setup(opts) end return M diff --git a/lua/nvim-tree/renderer/components/padding.lua b/lua/nvim-tree/renderer/components/padding.lua index be84ae0b9de..5003f53a235 100644 --- a/lua/nvim-tree/renderer/components/padding.lua +++ b/lua/nvim-tree/renderer/components/padding.lua @@ -1,3 +1,5 @@ +local config = require("nvim-tree.config") + local DirectoryNode = require("nvim-tree.node.directory") local M = {} @@ -27,21 +29,21 @@ local function get_padding_indent_markers(depth, idx, nodes_number, markers, wit if depth > 0 then local has_folder_sibling = check_siblings_for_folder(node, with_arrows) - local indent = string.rep(" ", M.config.indent_width - 1) + local indent = string.rep(" ", config.g.renderer.indent_width - 1) markers[depth] = idx ~= nodes_number for i = 1, depth - early_stop do local glyph if idx == nodes_number and i == depth then - local bottom_width = M.config.indent_width - 2 + (with_arrows and not inline_arrows and has_folder_sibling and 2 or 0) - glyph = M.config.indent_markers.icons.corner - .. string.rep(M.config.indent_markers.icons.bottom, bottom_width) - .. (M.config.indent_width > 1 and " " or "") + local bottom_width = config.g.renderer.indent_width - 2 + (with_arrows and not inline_arrows and has_folder_sibling and 2 or 0) + glyph = config.g.renderer.indent_markers.icons.corner + .. string.rep(config.g.renderer.indent_markers.icons.bottom, bottom_width) + .. (config.g.renderer.indent_width > 1 and " " or "") elseif markers[i] and i == depth then - glyph = M.config.indent_markers.icons.item .. indent + glyph = config.g.renderer.indent_markers.icons.item .. indent elseif markers[i] then - glyph = M.config.indent_markers.icons.edge .. indent + glyph = config.g.renderer.indent_markers.icons.edge .. indent else - glyph = M.config.indent_markers.icons.none .. indent + glyph = config.g.renderer.indent_markers.icons.none .. indent end if not with_arrows or (inline_arrows and (depth ~= i or not node.nodes)) then @@ -68,10 +70,10 @@ end function M.get_indent_markers(depth, idx, nodes_number, node, markers, early_stop) local str = "" - local show_arrows = M.config.icons.show.folder_arrow - local show_markers = M.config.indent_markers.enable - local inline_arrows = M.config.indent_markers.inline_arrows - local indent_width = M.config.indent_width + local show_arrows = config.g.renderer.icons.show.folder_arrow + local show_markers = config.g.renderer.indent_markers.enable + local inline_arrows = config.g.renderer.indent_markers.inline_arrows + local indent_width = config.g.renderer.indent_width if show_markers then str = str .. get_padding_indent_markers(depth, idx, nodes_number, markers, show_arrows, inline_arrows, node, early_stop or 0) @@ -85,7 +87,7 @@ end ---@param node Node ---@return nvim_tree.api.highlighted_string[]? function M.get_arrows(node) - if not M.config.icons.show.folder_arrow then + if not config.g.renderer.icons.show.folder_arrow then return end @@ -95,38 +97,18 @@ function M.get_arrows(node) local dir = node:as(DirectoryNode) if dir then if dir.open then - str = M.config.icons.glyphs.folder["arrow_open"] .. M.config.icons.padding.folder_arrow + str = config.g.renderer.icons.glyphs.folder["arrow_open"] .. config.g.renderer.icons.padding.folder_arrow hl = "NvimTreeFolderArrowOpen" else - str = M.config.icons.glyphs.folder["arrow_closed"] .. M.config.icons.padding.folder_arrow + str = config.g.renderer.icons.glyphs.folder["arrow_closed"] .. config.g.renderer.icons.padding.folder_arrow end - elseif M.config.indent_markers.enable then + elseif config.g.renderer.indent_markers.enable then str = "" else - str = " " .. string.rep(" ", #M.config.icons.padding.folder_arrow) + str = " " .. string.rep(" ", #config.g.renderer.icons.padding.folder_arrow) end return { str = str, hl = { hl } } end -function M.setup(opts) - M.config = opts.renderer - - if M.config.indent_width < 1 then - M.config.indent_width = 1 - end - - local function check_marker(symbol) - if #symbol == 0 then - return " " - end - -- return the first character from the UTF-8 encoded string; we may use utf8.codes from Lua 5.3 when available - return symbol:match("[%z\1-\127\194-\244][\128-\191]*") - end - - for k, v in pairs(M.config.indent_markers.icons) do - M.config.indent_markers.icons[k] = check_marker(v) - end -end - return M From 95aadfffc34a8138cc0c72bfd6d3c30acf428e17 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Fri, 27 Mar 2026 14:40:08 +1100 Subject: [PATCH 27/27] Revert "perf(#3257): remove padding setup" This reverts commit 862db0366beb7ff4c7738881dd8fe80ebfd6b92f. --- lua/nvim-tree/config.lua | 15 ----- lua/nvim-tree/renderer/components/init.lua | 2 + lua/nvim-tree/renderer/components/padding.lua | 56 ++++++++++++------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 44e54719236..5f44f811287 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -511,21 +511,6 @@ local function process_config(u) if u.actions.open_file.window_picker.chars then u.actions.open_file.window_picker.chars = tostring(u.actions.open_file.window_picker.chars):upper() end - - -- Padding and Indent Markers - if u.renderer.indent_width < 1 then - u.renderer.indent_width = 1 - end - local function check_marker(symbol) - if #symbol == 0 then - return " " - end - -- return the first character from the UTF-8 encoded string; we may use utf8.codes from Lua 5.3 when available - return symbol:match("[%z\1-\127\194-\244][\128-\191]*") - end - for k, v in pairs(u.renderer.indent_markers.icons) do - u.renderer.indent_markers.icons[k] = check_marker(v) - end end ---Validate user config and migrate legacy. diff --git a/lua/nvim-tree/renderer/components/init.lua b/lua/nvim-tree/renderer/components/init.lua index 38e20432533..a06827422dd 100644 --- a/lua/nvim-tree/renderer/components/init.lua +++ b/lua/nvim-tree/renderer/components/init.lua @@ -1,9 +1,11 @@ local M = {} M.devicons = require("nvim-tree.renderer.components.devicons") +M.padding = require("nvim-tree.renderer.components.padding") function M.setup(opts) M.devicons.setup(opts) + M.padding.setup(opts) end return M diff --git a/lua/nvim-tree/renderer/components/padding.lua b/lua/nvim-tree/renderer/components/padding.lua index 5003f53a235..be84ae0b9de 100644 --- a/lua/nvim-tree/renderer/components/padding.lua +++ b/lua/nvim-tree/renderer/components/padding.lua @@ -1,5 +1,3 @@ -local config = require("nvim-tree.config") - local DirectoryNode = require("nvim-tree.node.directory") local M = {} @@ -29,21 +27,21 @@ local function get_padding_indent_markers(depth, idx, nodes_number, markers, wit if depth > 0 then local has_folder_sibling = check_siblings_for_folder(node, with_arrows) - local indent = string.rep(" ", config.g.renderer.indent_width - 1) + local indent = string.rep(" ", M.config.indent_width - 1) markers[depth] = idx ~= nodes_number for i = 1, depth - early_stop do local glyph if idx == nodes_number and i == depth then - local bottom_width = config.g.renderer.indent_width - 2 + (with_arrows and not inline_arrows and has_folder_sibling and 2 or 0) - glyph = config.g.renderer.indent_markers.icons.corner - .. string.rep(config.g.renderer.indent_markers.icons.bottom, bottom_width) - .. (config.g.renderer.indent_width > 1 and " " or "") + local bottom_width = M.config.indent_width - 2 + (with_arrows and not inline_arrows and has_folder_sibling and 2 or 0) + glyph = M.config.indent_markers.icons.corner + .. string.rep(M.config.indent_markers.icons.bottom, bottom_width) + .. (M.config.indent_width > 1 and " " or "") elseif markers[i] and i == depth then - glyph = config.g.renderer.indent_markers.icons.item .. indent + glyph = M.config.indent_markers.icons.item .. indent elseif markers[i] then - glyph = config.g.renderer.indent_markers.icons.edge .. indent + glyph = M.config.indent_markers.icons.edge .. indent else - glyph = config.g.renderer.indent_markers.icons.none .. indent + glyph = M.config.indent_markers.icons.none .. indent end if not with_arrows or (inline_arrows and (depth ~= i or not node.nodes)) then @@ -70,10 +68,10 @@ end function M.get_indent_markers(depth, idx, nodes_number, node, markers, early_stop) local str = "" - local show_arrows = config.g.renderer.icons.show.folder_arrow - local show_markers = config.g.renderer.indent_markers.enable - local inline_arrows = config.g.renderer.indent_markers.inline_arrows - local indent_width = config.g.renderer.indent_width + local show_arrows = M.config.icons.show.folder_arrow + local show_markers = M.config.indent_markers.enable + local inline_arrows = M.config.indent_markers.inline_arrows + local indent_width = M.config.indent_width if show_markers then str = str .. get_padding_indent_markers(depth, idx, nodes_number, markers, show_arrows, inline_arrows, node, early_stop or 0) @@ -87,7 +85,7 @@ end ---@param node Node ---@return nvim_tree.api.highlighted_string[]? function M.get_arrows(node) - if not config.g.renderer.icons.show.folder_arrow then + if not M.config.icons.show.folder_arrow then return end @@ -97,18 +95,38 @@ function M.get_arrows(node) local dir = node:as(DirectoryNode) if dir then if dir.open then - str = config.g.renderer.icons.glyphs.folder["arrow_open"] .. config.g.renderer.icons.padding.folder_arrow + str = M.config.icons.glyphs.folder["arrow_open"] .. M.config.icons.padding.folder_arrow hl = "NvimTreeFolderArrowOpen" else - str = config.g.renderer.icons.glyphs.folder["arrow_closed"] .. config.g.renderer.icons.padding.folder_arrow + str = M.config.icons.glyphs.folder["arrow_closed"] .. M.config.icons.padding.folder_arrow end - elseif config.g.renderer.indent_markers.enable then + elseif M.config.indent_markers.enable then str = "" else - str = " " .. string.rep(" ", #config.g.renderer.icons.padding.folder_arrow) + str = " " .. string.rep(" ", #M.config.icons.padding.folder_arrow) end return { str = str, hl = { hl } } end +function M.setup(opts) + M.config = opts.renderer + + if M.config.indent_width < 1 then + M.config.indent_width = 1 + end + + local function check_marker(symbol) + if #symbol == 0 then + return " " + end + -- return the first character from the UTF-8 encoded string; we may use utf8.codes from Lua 5.3 when available + return symbol:match("[%z\1-\127\194-\244][\128-\191]*") + end + + for k, v in pairs(M.config.indent_markers.icons) do + M.config.indent_markers.icons[k] = check_marker(v) + end +end + return M