Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/nvim-tree/actions/finders/find-file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function M.fn(path)
dir.open = true
end
if #dir.nodes == 0 then
core.get_explorer():expand(dir)
core.get_explorer():expand_dir_node(dir)
if dir.group_next and incremented_line then
line = line - 1
end
Expand Down
1 change: 0 additions & 1 deletion lua/nvim-tree/actions/tree/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ M.resize = require("nvim-tree.actions.tree.resize")

function M.setup(opts)
M.find_file.setup(opts)
M.modifiers.setup(opts)
M.open.setup(opts)
M.toggle.setup(opts)
M.resize.setup(opts)
Expand Down
165 changes: 0 additions & 165 deletions lua/nvim-tree/actions/tree/modifiers/expand.lua

This file was deleted.

5 changes: 0 additions & 5 deletions lua/nvim-tree/actions/tree/modifiers/init.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
local M = {}

M.collapse = require("nvim-tree.actions.tree.modifiers.collapse")
M.expand = require("nvim-tree.actions.tree.modifiers.expand")

function M.setup(opts)
M.expand.setup(opts)
end

return M
4 changes: 2 additions & 2 deletions lua/nvim-tree/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ Api.tree.collapse_all = wrap(actions.tree.modifiers.collapse.all)
---@class ApiTreeExpandOpts
---@field expand_until (fun(expansion_count: integer, node: Node): boolean)|nil

Api.tree.expand_all = wrap_node(actions.tree.modifiers.expand.all)
Api.tree.expand_all = wrap_node(wrap_explorer("expand_all"))
Api.tree.toggle_enable_filters = wrap_explorer_member("filters", "toggle")
Api.tree.toggle_gitignore_filter = wrap_explorer_member_args("filters", "toggle", "git_ignored")
Api.tree.toggle_git_clean_filter = wrap_explorer_member_args("filters", "toggle", "git_clean")
Expand Down Expand Up @@ -327,7 +327,7 @@ Api.node.navigate.diagnostics.prev_recursive = wrap_node(actions.moves.item.fn({
Api.node.navigate.opened.next = wrap_node(actions.moves.item.fn({ where = "next", what = "opened" }))
Api.node.navigate.opened.prev = wrap_node(actions.moves.item.fn({ where = "prev", what = "opened" }))

Api.node.expand = wrap_node(actions.tree.modifiers.expand.node)
Api.node.expand = wrap_node(wrap_explorer("expand_node"))
Api.node.collapse = wrap_node(actions.tree.modifiers.collapse.node)

---@class ApiNodeDeleteWipeBufferOpts
Expand Down
24 changes: 23 additions & 1 deletion lua/nvim-tree/explorer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ function Explorer:create_autocmds()
end

---@param node DirectoryNode
function Explorer:expand(node)
function Explorer:expand_dir_node(node)
self:_load(node)
end

Expand Down Expand Up @@ -683,6 +683,28 @@ function Explorer:get_nodes()
return self:clone()
end

---Expand the directory node or the root
---@param node Node
---@param expand_opts ApiTreeExpandOpts?
function Explorer:expand_all(node, expand_opts)
if node then
node:expand(expand_opts)
else
self.expand(self, expand_opts)
end
end

---Expand the directory node or parent node
---@param node Node
---@param expand_opts ApiTreeExpandOpts?
function Explorer:expand_node(node, expand_opts)
if not node then
return
end

node:expand(expand_opts)
end

function Explorer:setup(opts)
config = opts
end
Expand Down
128 changes: 127 additions & 1 deletion lua/nvim-tree/node/directory.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local git_utils = require("nvim-tree.git.utils")
local icons = require("nvim-tree.renderer.components.devicons")
local notify = require("nvim-tree.notify")
local Iterator = require("nvim-tree.iterators.node-iterator")

local Node = require("nvim-tree.node")

Expand Down Expand Up @@ -167,7 +168,7 @@ function DirectoryNode:expand_or_collapse(toggle_group)
end

if #self.nodes == 0 then
self.explorer:expand(self)
self.explorer:expand_dir_node(self)
end

local head_node = self:get_parent_of_group() or self
Expand Down Expand Up @@ -290,4 +291,129 @@ function DirectoryNode:clone(api_nodes)
return clone
end

---@private
---@param should_descend fun(expansion_count: integer, node: Node): boolean
---@return fun(expansion_count: integer, node: Node): boolean
function DirectoryNode:limit_folder_discovery(should_descend)
local MAX_FOLDER_DISCOVERY = self.explorer.opts.actions.expand_all.max_folder_discovery
Copy link
Member

Choose a reason for hiding this comment

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

Nice one. Reading it here will allow us to dynamically change actions.expand_all.max_folder_discovery

return function(expansion_count)
local should_halt = expansion_count >= MAX_FOLDER_DISCOVERY
if should_halt then
notify.warn("expansion iteration was halted after " .. MAX_FOLDER_DISCOVERY .. " discovered folders")
return false
end

return should_descend(expansion_count, self)
end
end

---@private
---@param list string[]
---@return table
local function to_lookup_table(list)
local table = {}
for _, element in ipairs(list) do
table[element] = true
end

return table
end

---@private
---@param _ integer expansion_count
---@return boolean
function DirectoryNode:descend_until_empty(_)
local EXCLUDE = to_lookup_table(self.explorer.opts.actions.expand_all.exclude)
Copy link
Member

Choose a reason for hiding this comment

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

Again nice, allows dynamic changes to actions.expand_all.exclude

local should_exclude = EXCLUDE[self.name]
return not should_exclude
end

---@private
---@param expansion_count integer
---@param node Node
---@param should_descend fun(expansion_count: integer, node: Node): boolean
---@return boolean
function DirectoryNode:should_expand(expansion_count, node, should_descend)
local dir = node:as(DirectoryNode)
if not dir then
return false
end

if not dir.open and should_descend(expansion_count, node) then
if #node.nodes == 0 then
self.explorer:expand_dir_node(dir) -- populate node.group_next
end

if dir.group_next then
local expand_next = self:should_expand(expansion_count, dir.group_next, should_descend)
if expand_next then
dir.open = true
end
return expand_next
else
return true
end
end
return false
end

---@private
---@param should_descend fun(expansion_count: integer, node: Node): boolean
---@return fun(node): any
function DirectoryNode:gen_iterator(should_descend)
local expansion_count = 0

return function(parent)
if parent.parent and parent.nodes and not parent.open then
expansion_count = expansion_count + 1
parent:expand_dir_node()
end

Iterator.builder(parent.nodes)
:hidden()
:applier(function(node)
if DirectoryNode:should_expand(expansion_count, node, should_descend) then
expansion_count = expansion_count + 1
node = node:as(DirectoryNode)
if node then
self:expand_dir_node()
end
end
end)
:recursor(function(node)
if not should_descend(expansion_count, node) then
return nil
end

if node.group_next then
return { node.group_next }
end

if node.open and node.nodes then
return node.nodes
end

return nil
end)
:iterate()
end
end

---@param expand_opts ApiTreeExpandOpts?
function DirectoryNode:expand(expand_opts)
local descend_until_empty_fn = self.descend_until_empty
local descend_until = self:limit_folder_discovery((expand_opts and expand_opts.expand_until) or descend_until_empty_fn)
self:gen_iterator(descend_until)(self)

self.explorer.renderer:draw()
end

function DirectoryNode:expand_dir_node()
local node = self:last_group_node()
node.open = true
if #node.nodes == 0 then
self.explorer:expand_dir_node(node)
end
end

return DirectoryNode
Loading
Loading