Skip to content

Conversation

@Uanela
Copy link

@Uanela Uanela commented Oct 30, 2025

fixes #2988

This PR is part of one of the Multi Instance tasks and aims to make a refactor moving the root actions change_dir and dir_up to the Explorer class.

PS: This is my first contribution to some nvim plugin, I've using nvim for almost 4-5 months now and become interested in getting involved into its Open source world.

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great, really happy with your contributions and it's working as per current behaviour.

Please:

The ones marked with a * will just go away if we move further with this refactor; see incoming comment.

local M = {}

---@param node Node
function M.fn(node)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has been moved to Explorer:dir_up and it's working beautifully there.
This is great as this function is now unused, therefore we can delete this whole file.


---@return boolean
local function should_change_dir()
local explorer = core.get_explorer()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable explorer is unused and has been identified by the linter: https://github.com/nvim-tree/nvim-tree.lua/actions/runs/18935214550/job/54313031114?pr=3209

This line should be deleted.


Api.tree.change_root_to_parent = wrap_node(actions.root.dir_up.fn)

Api.tree.change_root_to_parent = wrap_node(Explorer.dir_up)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change calls the new dir_up method. This isn't correct as the call is to the function Explorer.dir_up rather than the method Explorer:dir_up.
You can use

wrap_node(wrap_explorer("dir_up"))

instead. wrap_explorer will call dir_up as a method and wrap_node will pass the node.

Why is that a problem? When dir_up is called, self is set to the node, not explorer.
You can see this by adding some debug to the start of Explorer:dir_up

  require("nvim-tree.log").line("dev", "self %s", self and self.absolute_path or "no self")
  require("nvim-tree.log").line("dev", "node %s", node and node.absolute_path or "no node")

- on the data directory as per base test cases.

[2025-11-03 11:34:32] [dev] self /home/alex/src/keyd/data
[2025-11-03 11:34:32] [dev] node no node

Expected:

[2025-11-03 11:32:34] [dev] self /home/alex/src/keyd
[2025-11-03 11:32:34] [dev] node /home/alex/src/keyd/data

local function handle_buf_cwd(cwd)
if M.respect_buf_cwd and cwd ~= core.get_cwd() then
require("nvim-tree.actions.root.change-dir").fn(cwd)
require("lua.nvim-tree.explorer.change-dir").fn(cwd)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change requires the moved change-dir.lua module. It's throwing an exception as the module does not exist.
The require should be require("nvim-tree.explorer.change-dir")

See the exception in section "Fail: respect_buf_cwd = true" in the test document.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Unnecessary code gone!

return self:clone()
end

---@param node Node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotations are necessary for linting and LSP integration. Thank you for adding them.

end
end

Explorer.change_dir = change_dir
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explorer.change_dir is assigned to the Explorer class, instead of the instance. This isn't great as all Explorer instances will share the same change_dir.
It should be set to the instance during the constructor e.g. self.change_dir = ...

end
local newdir = vim.fn.fnamemodify(utils.path_remove_trailing(cwd), ":h")
require("nvim-tree.explorer.change-dir").fn(newdir)
require("nvim-tree.actions.finders.find-file").fn(node.absolute_path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module find-file is required inline instead of at the start of the module. This isn't desirable: all modules should be required only once at startup and shared. Inline requires can result in problems appearing at runtime rather than startup, as they are lazily evaluated.

local find_file = require("nvim-tree.actions.finders.find-file")

Why do we have some inline requires? There are circular dependencies that forced it. One of the goals of this refactoring work is to remove circular dependencies.

return
end
local newdir = vim.fn.fnamemodify(utils.path_remove_trailing(cwd), ":h")
require("nvim-tree.explorer.change-dir").fn(newdir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change-dir.lua module is required inline however we can use the change_dir member of Explorer. It could be simplified to:

M.change_dir.fn(newdir)

@alex-courtis
Copy link
Member

alex-courtis commented Nov 3, 2025

Testing with lua/nvim-tree/explorer/dir-up.lua deleted.

Success: Base Cases

Open /home/alex/src/keyd

:NvimTreeOpen

<C-]> data
:pwd
/home/alex/src/keyd/data

-
:pwd
/home/alex/src/keyd

-
:pwd
/home/alex/src

Fail: respect_buf_cwd = true

Open /home/alex/src/keyd

:NvimTreeOpen

-

q

:NvimTreeOpen

E5108: Error executing lua: ...ack/packer/start/nvim-tree.lua.dev/lua/nvim-tree/lib.lua:30: module 'lua.nvim-tree.explorer.change-dir' not found:
        no field package.preload['lua.nvim-tree.explorer.change-dir']
        no file '/usr/share/lua/5.4/lua/nvim-tree/explorer/change-dir.lua'
        ...
stack traceback:
        [C]: in function 'require'
        ...ack/packer/start/nvim-tree.lua.dev/lua/nvim-tree/lib.lua:30: in function 'handle_buf_cwd'
        ...ack/packer/start/nvim-tree.lua.dev/lua/nvim-tree/lib.lua:38: in function 'open_view_and_draw'
        ...ack/packer/start/nvim-tree.lua.dev/lua/nvim-tree/lib.lua:132: in function 'open'
        ...rt/nvim-tree.lua.dev/lua/nvim-tree/actions/tree/open.lua:32: in function 'open'
        /tmp/nd/config/nvim/nd.lua:52: in function </tmp/nd/config/nvim/nd.lua:52>

@alex-courtis
Copy link
Member

This is great, I'm happy to merge (following fixes) OR we can go further in this pull request OR go further in the next pull request.

You've refactored the dir_up functionality to be a method of Explorer which is the best case end state.

If you're keen we can do the same for ALL the change-dir.lua functionality: fn(input_cwd, with_open) can be changed to a method Explorer:change_dir. The local functions in change-dir.lua can be changed to ---@private explorer methods.

What's the advantage? The code will simplify greatly when they are part of the explorer class:

  • core.get_explorer() won't be necessary
  • config is available so we can remove setup
  • core.cwd() is unnecessary etc.
  • other code will just melt away as methods are moved

@alex-courtis alex-courtis changed the title Moving root actions change_dir and dir_up to the Explorer class refactor(#2988): multi instance explore: change_dir and dir_up Nov 3, 2025
@alex-courtis alex-courtis changed the title refactor(#2988): multi instance explore: change_dir and dir_up refactor(#2988): multi instance change_dir and dir_up Nov 3, 2025
@alex-courtis
Copy link
Member

FYI you can execute all the CI checks locally so that you don't have to wait for CI.

Once you've merged this PR I can add you as a repo member so that you can run CI checks yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi Instance: Refactor: move root actions to Explorer

2 participants