diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 8f03efab87f..2ea5c513cbc 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -568,6 +568,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. enable = true, global = false, restrict_above_cwd = false, + explorer_node_unchanged = false, }, expand_all = { max_folder_discovery = 300, @@ -1399,6 +1400,9 @@ vim |current-directory| behaviour. Restrict changing to a directory above the global cwd. Type: `boolean`, Default: `false` + *nvim-tree.actions.change_dir.explorer_node_unchanged* + Change dir with explorer nodes unchanged. + *nvim-tree.actions.expand_all* Configuration for expand_all behaviour. diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index f3260c47ac2..b6e7432b7dd 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -532,6 +532,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS enable = true, global = false, restrict_above_cwd = false, + explorer_node_unchanged = false, }, expand_all = { max_folder_discovery = 300, diff --git a/lua/nvim-tree/actions/root/change-dir.lua b/lua/nvim-tree/actions/root/change-dir.lua index 954b2081ccf..26fdf59a202 100644 --- a/lua/nvim-tree/actions/root/change-dir.lua +++ b/lua/nvim-tree/actions/root/change-dir.lua @@ -85,7 +85,11 @@ M.force_dirchange = add_profiling_to(function(foldername, should_open_view) if should_change_dir() then cd(M.options.global, foldername) end - core.init(foldername) + if M.options.explorer_node_unchanged then + core.change_root(foldername) + else + core.init(foldername) + end end if should_open_view then diff --git a/lua/nvim-tree/core.lua b/lua/nvim-tree/core.lua index 9a27458275e..c54da64065e 100644 --- a/lua/nvim-tree/core.lua +++ b/lua/nvim-tree/core.lua @@ -3,6 +3,8 @@ local explorer = require "nvim-tree.explorer" local live_filter = require "nvim-tree.live-filter" local view = require "nvim-tree.view" local log = require "nvim-tree.log" +local Iterator = require "nvim-tree.iterators.node-iterator" +local utils = require "nvim-tree.utils" local M = {} @@ -25,6 +27,49 @@ function M.init(foldername) log.profile_end(profile) end +---@param path string +function M.change_root(path) + if TreeExplorer == nil then + return + end + local root_parent_cwd = vim.fn.fnamemodify(utils.path_remove_trailing(TreeExplorer.absolute_path), ":h") + if root_parent_cwd == path then + local newTreeExplorer = explorer.Explorer.new(path) + if newTreeExplorer == nil then + return + end + for _, node in ipairs(newTreeExplorer.nodes) do + if node.absolute_path == TreeExplorer.absolute_path then + node.nodes = TreeExplorer.nodes + end + end + TreeExplorer:destroy() + TreeExplorer = newTreeExplorer + else + local newTreeExplorer = explorer.Explorer.new(path) + if newTreeExplorer == nil then + return + end + local child_node + Iterator.builder(TreeExplorer.nodes) + :hidden() + :applier(function(n) + if n.absolute_path == path then + child_node = n + end + end) + :recursor(function(n) + return n.group_next and { n.group_next } or n.nodes + end) + :iterate() + if #child_node.nodes ~= 0 then + newTreeExplorer.nodes = child_node.nodes; + end + TreeExplorer:destroy() + TreeExplorer = newTreeExplorer + end +end + ---@return Explorer|nil function M.get_explorer() return TreeExplorer