Skip to content

Commit 89d9621

Browse files
authored
refactor(#3225): multi instance expand (#3234)
* wip(explorer): rename :expand to :expand_dir_node and all places using it * wip: move expand function to directory * refactor: move expand functionality to node methods Move expansion logic from actions/tree/modifiers/expand.lua into DirectoryNode and Explorer methods. Update API to use new methods via wrap_explorer. Remove expand module and its setup calls. * refactor(directory): correctly calling class methods and passing correct values * fix: moving directory and file nodes require to avoid circular depency * fix(node): correctly calling expand on parent without circular dependency * fix(node.directory): fix <E> not expanding all folders * refactor(node.director): move gen_iterator to expand and safely call descend_until_empty * feat: move collapse to tree actions and remove modifiers folder * feat: move should_expand to Node for better OO * chore: add should_expand in DirectoryNode to avoid circular dependecy * fix(explorer): correctly calling expand as a class method * fix: adding underscore on unsed variables * chore: move descend_until_empty to local function * fix(directory): correctly pass node instead of self ot should_descend
1 parent b93dbb9 commit 89d9621

File tree

8 files changed

+148
-181
lines changed

8 files changed

+148
-181
lines changed
File renamed without changes.

lua/nvim-tree/actions/tree/init.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
local M = {}
22

33
M.find_file = require("nvim-tree.actions.tree.find-file")
4-
M.modifiers = require("nvim-tree.actions.tree.modifiers")
4+
M.collapse = require("nvim-tree.actions.tree.collapse")
55
M.open = require("nvim-tree.actions.tree.open")
66
M.toggle = require("nvim-tree.actions.tree.toggle")
77
M.resize = require("nvim-tree.actions.tree.resize")
88

99
function M.setup(opts)
1010
M.find_file.setup(opts)
11-
M.modifiers.setup(opts)
1211
M.open.setup(opts)
1312
M.toggle.setup(opts)
1413
M.resize.setup(opts)

lua/nvim-tree/actions/tree/modifiers/expand.lua

Lines changed: 0 additions & 165 deletions
This file was deleted.

lua/nvim-tree/actions/tree/modifiers/init.lua

Lines changed: 0 additions & 10 deletions
This file was deleted.

lua/nvim-tree/api.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,12 @@ Api.tree.search_node = wrap(actions.finders.search_node.fn)
176176
---@class ApiCollapseOpts
177177
---@field keep_buffers boolean|nil default false
178178

179-
Api.tree.collapse_all = wrap(actions.tree.modifiers.collapse.all)
179+
Api.tree.collapse_all = wrap(actions.tree.collapse.all)
180180

181181
---@class ApiTreeExpandOpts
182182
---@field expand_until (fun(expansion_count: integer, node: Node): boolean)|nil
183183

184-
Api.tree.expand_all = wrap_node(actions.tree.modifiers.expand.all)
184+
Api.tree.expand_all = wrap_node(wrap_explorer("expand_all"))
185185
Api.tree.toggle_enable_filters = wrap_explorer_member("filters", "toggle")
186186
Api.tree.toggle_gitignore_filter = wrap_explorer_member_args("filters", "toggle", "git_ignored")
187187
Api.tree.toggle_git_clean_filter = wrap_explorer_member_args("filters", "toggle", "git_clean")
@@ -310,8 +310,8 @@ Api.node.navigate.diagnostics.prev_recursive = wrap_node(actions.moves.item.fn({
310310
Api.node.navigate.opened.next = wrap_node(actions.moves.item.fn({ where = "next", what = "opened" }))
311311
Api.node.navigate.opened.prev = wrap_node(actions.moves.item.fn({ where = "prev", what = "opened" }))
312312

313-
Api.node.expand = wrap_node(actions.tree.modifiers.expand.node)
314-
Api.node.collapse = wrap_node(actions.tree.modifiers.collapse.node)
313+
Api.node.expand = wrap_node(wrap_explorer("expand_node"))
314+
Api.node.collapse = wrap_node(actions.tree.collapse.node)
315315

316316
---@class ApiNodeDeleteWipeBufferOpts
317317
---@field force boolean|nil default false

lua/nvim-tree/explorer/init.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,28 @@ function Explorer:get_nodes()
687687
return self:clone()
688688
end
689689

690+
---Expand the directory node or the root
691+
---@param node Node
692+
---@param expand_opts ApiTreeExpandOpts?
693+
function Explorer:expand_all(node, expand_opts)
694+
if node then
695+
node:expand(expand_opts)
696+
else
697+
self:expand(expand_opts)
698+
end
699+
end
700+
701+
---Expand the directory node or parent node
702+
---@param node Node
703+
---@param expand_opts ApiTreeExpandOpts?
704+
function Explorer:expand_node(node, expand_opts)
705+
if not node then
706+
return
707+
end
708+
709+
node:expand(expand_opts)
710+
end
711+
690712
---@private
691713
---@param new_tabpage integer
692714
---@return boolean

lua/nvim-tree/node/directory.lua

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local git_utils = require("nvim-tree.git.utils")
22
local icons = require("nvim-tree.renderer.components.devicons")
33
local notify = require("nvim-tree.notify")
4+
local Iterator = require("nvim-tree.iterators.node-iterator")
45

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

@@ -290,4 +291,110 @@ function DirectoryNode:clone(api_nodes)
290291
return clone
291292
end
292293

294+
---@private
295+
---@param should_descend fun(expansion_count: integer, node: Node): boolean
296+
---@return fun(expansion_count: integer, node: Node): boolean
297+
function DirectoryNode:limit_folder_discovery(should_descend)
298+
local MAX_FOLDER_DISCOVERY = self.explorer.opts.actions.expand_all.max_folder_discovery
299+
return function(expansion_count, node)
300+
local should_halt = expansion_count >= MAX_FOLDER_DISCOVERY
301+
if should_halt then
302+
notify.warn("expansion iteration was halted after " .. MAX_FOLDER_DISCOVERY .. " discovered folders")
303+
return false
304+
end
305+
306+
return should_descend(expansion_count, node)
307+
end
308+
end
309+
310+
---@param expansion_count integer
311+
---@param should_descend fun(expansion_count: integer, node: Node): boolean
312+
---@return boolean
313+
function DirectoryNode:should_expand(expansion_count, should_descend)
314+
if not self.open and should_descend(expansion_count, self) then
315+
if #self.nodes == 0 then
316+
self.explorer:expand_dir_node(self) -- populate node.group_next
317+
end
318+
319+
if self.group_next then
320+
local expand_next = self.group_next:should_expand(expansion_count, should_descend)
321+
if expand_next then
322+
self.open = true
323+
end
324+
return expand_next
325+
else
326+
return true
327+
end
328+
end
329+
return false
330+
end
331+
332+
---@param list string[]
333+
---@return table
334+
local function to_lookup_table(list)
335+
local table = {}
336+
for _, element in ipairs(list) do
337+
table[element] = true
338+
end
339+
340+
return table
341+
end
342+
343+
---@param _ integer
344+
---@param node Node
345+
---@return boolean
346+
local function descend_until_empty(_, node)
347+
local EXCLUDE = to_lookup_table(node.explorer.opts.actions.expand_all.exclude)
348+
local should_exclude = EXCLUDE[node.name]
349+
return not should_exclude
350+
end
351+
352+
---@param expand_opts ApiTreeExpandOpts?
353+
function DirectoryNode:expand(expand_opts)
354+
local expansion_count = 0
355+
356+
local should_descend = self:limit_folder_discovery((expand_opts and expand_opts.expand_until) or descend_until_empty)
357+
358+
359+
if self.parent and self.nodes and not self.open then
360+
expansion_count = expansion_count + 1
361+
self:expand_dir_node()
362+
end
363+
364+
Iterator.builder(self.nodes)
365+
:hidden()
366+
:applier(function(node)
367+
if node:should_expand(expansion_count, should_descend) then
368+
expansion_count = expansion_count + 1
369+
node:expand_dir_node()
370+
end
371+
end)
372+
:recursor(function(node)
373+
if not should_descend(expansion_count, node) then
374+
return nil
375+
end
376+
377+
if node.group_next then
378+
return { node.group_next }
379+
end
380+
381+
if node.open and node.nodes then
382+
return node.nodes
383+
end
384+
385+
return nil
386+
end)
387+
:iterate()
388+
389+
self.explorer.renderer:draw()
390+
end
391+
392+
function DirectoryNode:expand_dir_node()
393+
local node = self:last_group_node()
394+
node.open = true
395+
if #node.nodes == 0 then
396+
self.explorer:expand_dir_node(node)
397+
end
398+
end
399+
293400
return DirectoryNode

lua/nvim-tree/node/init.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,18 @@ function Node:clone(api_nodes)
144144
return clone
145145
end
146146

147+
---@param _expansion_count integer
148+
---@param _should_descend fun(expansion_count: integer, node: Node): boolean
149+
---@return boolean
150+
function Node:should_expand(_expansion_count, _should_descend)
151+
return false
152+
end
153+
154+
---@param expand_opts ApiTreeExpandOpts?
155+
function Node:expand(expand_opts)
156+
if self.parent then
157+
self.parent:expand(expand_opts)
158+
end
159+
end
160+
147161
return Node

0 commit comments

Comments
 (0)