Skip to content

Commit d4242af

Browse files
committed
temporarily move DirectoryNode methods into BaseNode for easier reviewing
1 parent ccf43b0 commit d4242af

File tree

2 files changed

+140
-127
lines changed

2 files changed

+140
-127
lines changed

lua/nvim-tree/node/directory.lua

Lines changed: 2 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ local BaseNode = require("nvim-tree.node")
99
---@field nodes Node[]
1010
---@field open boolean
1111
---@field hidden_stats table? -- Each field of this table is a key for source and value for count
12-
local DirectoryNode = BaseNode:new()
12+
local DirectoryNode = BaseNode.dn
13+
-- local DirectoryNode = BaseNode:new()
1314

1415
---Static factory method
1516
---@param explorer Explorer
@@ -59,117 +60,13 @@ function DirectoryNode:destroy()
5960
end
6061
end
6162

62-
---@return boolean
63-
function DirectoryNode:has_one_child_folder()
64-
return #self.nodes == 1 and self.nodes[1].nodes and vim.loop.fs_access(self.nodes[1].absolute_path, "R") or false
65-
end
66-
67-
-- If node is grouped, return the last node in the group. Otherwise, return the given node.
68-
---@return Node
69-
function DirectoryNode:last_group_node()
70-
local node = self --[[@as BaseNode]]
71-
72-
while node.group_next do
73-
node = node.group_next
74-
end
75-
76-
return node
77-
end
78-
79-
---Group empty folders
80-
-- Recursively group nodes
81-
---@return Node[]
82-
function DirectoryNode:group_empty_folders()
83-
local is_root = not self.parent
84-
local child_folder_only = self:has_one_child_folder() and self.nodes[1]
85-
if self.explorer.opts.renderer.group_empty and not is_root and child_folder_only then
86-
self.group_next = child_folder_only
87-
local ns = child_folder_only:group_empty_folders()
88-
self.nodes = ns or {}
89-
return ns
90-
end
91-
return self.nodes
92-
end
93-
94-
---Ungroup empty folders
95-
-- If a node is grouped, ungroup it: put node.group_next to the node.nodes and set node.group_next to nil
96-
function DirectoryNode:ungroup_empty_folders()
97-
local cur = self
98-
while cur and cur.group_next do
99-
cur.nodes = { cur.group_next }
100-
cur.group_next = nil
101-
cur = cur.nodes[1]
102-
end
103-
end
104-
10563
---Update the GitStatus of absolute path of the directory
10664
---@param parent_ignored boolean
10765
---@param status table|nil
10866
function DirectoryNode:update_git_status(parent_ignored, status)
10967
self.git_status = git.git_status_dir(parent_ignored, status, self.absolute_path)
11068
end
11169

112-
---@return GitStatus|nil
113-
function BaseNode:get_git_status()
114-
if not self.git_status or not self.explorer.opts.git.show_on_dirs then
115-
return nil
116-
end
117-
118-
local status = {}
119-
if not self:last_group_node().open or self.explorer.opts.git.show_on_open_dirs then
120-
-- dir is closed or we should show on open_dirs
121-
if self.git_status.file ~= nil then
122-
table.insert(status, self.git_status.file)
123-
end
124-
if self.git_status.dir ~= nil then
125-
if self.git_status.dir.direct ~= nil then
126-
for _, s in pairs(self.git_status.dir.direct) do
127-
table.insert(status, s)
128-
end
129-
end
130-
if self.git_status.dir.indirect ~= nil then
131-
for _, s in pairs(self.git_status.dir.indirect) do
132-
table.insert(status, s)
133-
end
134-
end
135-
end
136-
else
137-
-- dir is open and we shouldn't show on open_dirs
138-
if self.git_status.file ~= nil then
139-
table.insert(status, self.git_status.file)
140-
end
141-
if self.git_status.dir ~= nil and self.git_status.dir.direct ~= nil then
142-
local deleted = {
143-
[" D"] = true,
144-
["D "] = true,
145-
["RD"] = true,
146-
["DD"] = true,
147-
}
148-
for _, s in pairs(self.git_status.dir.direct) do
149-
if deleted[s] then
150-
table.insert(status, s)
151-
end
152-
end
153-
end
154-
end
155-
if #status == 0 then
156-
return nil
157-
else
158-
return status
159-
end
160-
end
161-
162-
---@param projects table
163-
function DirectoryNode:reload_node_status(projects)
164-
local toplevel = git.get_toplevel(self.absolute_path)
165-
local status = projects[toplevel] or {}
166-
for _, node in ipairs(self.nodes) do
167-
node:update_git_status(self:is_git_ignored(), status)
168-
if node.nodes and #node.nodes > 0 then
169-
self:reload_node_status(projects)
170-
end
171-
end
172-
end
17370

17471
---Create a sanitized partial copy of a node, populating children recursively.
17572
---@return DirectoryNode cloned

lua/nvim-tree/node/init.lua

Lines changed: 138 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local git = require("nvim-tree.git")
22

3+
---TODO remove all @cast, @as
34
---TODO remove all references to directory fields:
45
------@field has_children boolean
56
------@field group_next Node? -- If node is grouped, this points to the next child dir/link node
@@ -38,6 +39,11 @@ function BaseNode:new(o)
3839
return o
3940
end
4041

42+
-- TODO temporary hack to allow DirectoryNode methods in this file, for easier reviewing
43+
---@class DirectoryNode
44+
local DirectoryNode = BaseNode:new()
45+
BaseNode.dn = DirectoryNode ---@diagnostic disable-line: inject-field
46+
4147
function BaseNode:destroy()
4248
if self.watcher then
4349
self.watcher:destroy()
@@ -63,25 +69,8 @@ function BaseNode:is(T)
6369
end
6470

6571
---@return boolean
66-
function BaseNode:has_one_child_folder()
67-
return false
68-
end
69-
70-
-- If node is grouped, return the last node in the group. Otherwise, return the given node.
71-
---@return Node
72-
function BaseNode:last_group_node()
73-
return self
74-
end
75-
76-
---Group empty folders
77-
-- Recursively group nodes
78-
---@return Node[]
79-
function BaseNode:group_empty_folders()
80-
return {}
81-
end
82-
83-
---Ungroup empty folders
84-
function BaseNode:ungroup_empty_folders()
72+
function DirectoryNode:has_one_child_folder()
73+
return #self.nodes == 1 and self.nodes[1].nodes and vim.loop.fs_access(self.nodes[1].absolute_path, "R") or false
8574
end
8675

8776
---Update the GitStatus of the node
@@ -94,8 +83,66 @@ end
9483
function BaseNode:get_git_status()
9584
end
9685

97-
---@param _ table projects
98-
function BaseNode:reload_node_status(_)
86+
---@return GitStatus|nil
87+
function DirectoryNode:get_git_status()
88+
if not self.git_status or not self.explorer.opts.git.show_on_dirs then
89+
return nil
90+
end
91+
92+
local status = {}
93+
if not self:last_group_node().open or self.explorer.opts.git.show_on_open_dirs then
94+
-- dir is closed or we should show on open_dirs
95+
if self.git_status.file ~= nil then
96+
table.insert(status, self.git_status.file)
97+
end
98+
if self.git_status.dir ~= nil then
99+
if self.git_status.dir.direct ~= nil then
100+
for _, s in pairs(self.git_status.dir.direct) do
101+
table.insert(status, s)
102+
end
103+
end
104+
if self.git_status.dir.indirect ~= nil then
105+
for _, s in pairs(self.git_status.dir.indirect) do
106+
table.insert(status, s)
107+
end
108+
end
109+
end
110+
else
111+
-- dir is open and we shouldn't show on open_dirs
112+
if self.git_status.file ~= nil then
113+
table.insert(status, self.git_status.file)
114+
end
115+
if self.git_status.dir ~= nil and self.git_status.dir.direct ~= nil then
116+
local deleted = {
117+
[" D"] = true,
118+
["D "] = true,
119+
["RD"] = true,
120+
["DD"] = true,
121+
}
122+
for _, s in pairs(self.git_status.dir.direct) do
123+
if deleted[s] then
124+
table.insert(status, s)
125+
end
126+
end
127+
end
128+
end
129+
if #status == 0 then
130+
return nil
131+
else
132+
return status
133+
end
134+
end
135+
136+
---@param projects table
137+
function DirectoryNode:reload_node_status(projects)
138+
local toplevel = git.get_toplevel(self.absolute_path)
139+
local status = projects[toplevel] or {}
140+
for _, node in ipairs(self.nodes) do
141+
node:update_git_status(self:is_git_ignored(), status)
142+
if node.nodes and #node.nodes > 0 then
143+
self:reload_node_status(projects)
144+
end
145+
end
99146
end
100147

101148
---@return boolean
@@ -116,6 +163,18 @@ function BaseNode:is_dotfile()
116163
return false
117164
end
118165

166+
-- If node is grouped, return the last node in the group. Otherwise, return the given node.
167+
---@return Node
168+
function DirectoryNode:last_group_node()
169+
local node = self --[[@as BaseNode]]
170+
171+
while node.group_next do
172+
node = node.group_next
173+
end
174+
175+
return node
176+
end
177+
119178
---@param project table?
120179
---@param root string?
121180
function BaseNode:update_parent_statuses(project, root)
@@ -186,7 +245,7 @@ function BaseNode:get_all_nodes_in_group()
186245
end
187246

188247
-- Toggle group empty folders
189-
function BaseNode:toggle_group_folders()
248+
function DirectoryNode:toggle_group_folders()
190249
local is_grouped = self.group_next ~= nil
191250

192251
if is_grouped then
@@ -196,6 +255,32 @@ function BaseNode:toggle_group_folders()
196255
end
197256
end
198257

258+
---Group empty folders
259+
-- Recursively group nodes
260+
---@return Node[]
261+
function DirectoryNode:group_empty_folders()
262+
local is_root = not self.parent
263+
local child_folder_only = self:has_one_child_folder() and self.nodes[1]
264+
if self.explorer.opts.renderer.group_empty and not is_root and child_folder_only then
265+
self.group_next = child_folder_only
266+
local ns = child_folder_only:group_empty_folders()
267+
self.nodes = ns or {}
268+
return ns
269+
end
270+
return self.nodes
271+
end
272+
273+
---Ungroup empty folders
274+
-- If a node is grouped, ungroup it: put node.group_next to the node.nodes and set node.group_next to nil
275+
function DirectoryNode:ungroup_empty_folders()
276+
local cur = self --[[@as DirectoryNode]]
277+
while cur and cur.group_next do
278+
cur.nodes = { cur.group_next }
279+
cur.group_next = nil
280+
cur = cur.nodes[1] --[[@as DirectoryNode]]
281+
end
282+
end
283+
199284
function BaseNode:expand_or_collapse(toggle_group)
200285
toggle_group = toggle_group or false
201286
if self.has_children then
@@ -208,6 +293,7 @@ function BaseNode:expand_or_collapse(toggle_group)
208293
end
209294

210295
local head_node = self:get_parent_of_group()
296+
---@cast head_node DirectoryNode -- TODO move this to the class
211297
if toggle_group then
212298
head_node:toggle_group_folders()
213299
end
@@ -251,4 +337,34 @@ function BaseNode:clone()
251337
return clone
252338
end
253339

340+
--
341+
-- TODO temporary hack to allow DirectoryNode methods in this file, for easier reviewing
342+
--
343+
344+
---@return boolean
345+
function BaseNode:has_one_child_folder()
346+
return false
347+
end
348+
349+
---@param _ table projects
350+
function BaseNode:reload_node_status(_)
351+
end
352+
353+
-- If node is grouped, return the last node in the group. Otherwise, return the given node.
354+
---@return Node
355+
function BaseNode:last_group_node()
356+
return self
357+
end
358+
359+
---Group empty folders
360+
-- Recursively group nodes
361+
---@return Node[]
362+
function BaseNode:group_empty_folders()
363+
return {}
364+
end
365+
366+
---Ungroup empty folders
367+
function BaseNode:ungroup_empty_folders()
368+
end
369+
254370
return BaseNode

0 commit comments

Comments
 (0)