Skip to content

Commit ac302ae

Browse files
committed
typechecked optargs constructors for nodes
1 parent 359398d commit ac302ae

File tree

12 files changed

+141
-126
lines changed

12 files changed

+141
-126
lines changed

lua/nvim-tree/classic.lua

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ Object.__index = Object ---@diagnostic disable-line: inject-field
1919
function Object:new(...)
2020
end
2121

22-
---Extend a class T
23-
---super will be set to T
24-
---@generic T
25-
---@param self T
26-
---@return T
22+
---Extend a class, setting .super
2723
function Object:extend()
2824
local cls = {}
2925
for k, v in pairs(self) do
@@ -38,10 +34,11 @@ function Object:extend()
3834
end
3935

4036
---Implement the functions of a mixin
41-
---Add the mixin to the implements table
37+
---Add the mixin to .implements
4238
---@param class Object
4339
function Object:implement(class)
4440
if not rawget(self, "implements") then
41+
-- set on the class itself instead of parents
4542
rawset(self, "implements", {})
4643
end
4744
self.implements[class] = true
@@ -78,11 +75,7 @@ function Object:as(class)
7875
return self:is(class) and self or nil
7976
end
8077

81-
---Constructor that invokes :new on a new instance
82-
---@generic T
83-
---@param self T
84-
---@param ... any
85-
---@return T
78+
---Constructor to create instance, call :new and return
8679
function Object:__call(...)
8780
local obj = setmetatable({}, self)
8881
obj:new(...)

lua/nvim-tree/core.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function M.init(foldername)
2525
path, err = vim.loop.cwd()
2626
end
2727
if path then
28-
TreeExplorer = require("nvim-tree.explorer")(path)
28+
TreeExplorer = require("nvim-tree.explorer")({ path = path })
2929
else
3030
notify.error(err)
3131
TreeExplorer = nil

lua/nvim-tree/enum.lua

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
local M = {}
22

3-
---Must be synced with uv.fs_stat.result as it is compared with it
4-
---@enum (key) NODE_TYPE
5-
M.NODE_TYPE = {
6-
directory = 1,
7-
file = 2,
8-
link = 4,
9-
}
10-
113
---Setup options for "highlight_*"
124
---@enum HL_POSITION
135
M.HL_POSITION = {

lua/nvim-tree/explorer/init.lua

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,19 @@ local config
3737
---@field clipboard Clipboard
3838
local Explorer = RootNode:extend()
3939

40-
---@param path string
41-
function Explorer:new(path)
42-
Explorer.super.new(self, self, path, "..", nil)
40+
---@class Explorer
41+
---@overload fun(opts: ExplorerArgs): Explorer
42+
43+
---@class (exact) ExplorerArgs
44+
---@field path string
45+
46+
---@param args ExplorerArgs
47+
function Explorer:new(args)
48+
Explorer.super.new(self, {
49+
explorer = self,
50+
absolute_path = args.path,
51+
name = "..",
52+
})
4353

4454
self.uid_explorer = vim.loop.hrtime()
4555
self.augroup_id = vim.api.nvim_create_augroup("NvimTree_Explorer_" .. self.uid_explorer, {})
@@ -222,7 +232,13 @@ function Explorer:reload(node, project)
222232
end
223233

224234
if not nodes_by_path[abs] then
225-
local new_child = node_factory.create_node(self, node, abs, stat, name)
235+
local new_child = node_factory.create({
236+
explorer = self,
237+
parent = node,
238+
absolute_path = abs,
239+
name = name,
240+
fs_stat = stat
241+
})
226242
if new_child then
227243
table.insert(node.nodes, new_child)
228244
nodes_by_path[abs] = new_child
@@ -360,7 +376,13 @@ function Explorer:populate_children(handle, cwd, node, project, parent)
360376
local stat = vim.loop.fs_lstat(abs)
361377
local filter_reason = parent.filters:should_filter_as_reason(abs, stat, filter_status)
362378
if filter_reason == FILTER_REASON.none and not nodes_by_path[abs] then
363-
local child = node_factory.create_node(self, node, abs, stat, name)
379+
local child = node_factory.create({
380+
explorer = self,
381+
parent = node,
382+
absolute_path = abs,
383+
name = name,
384+
fs_stat = stat
385+
})
364386
if child then
365387
table.insert(node.nodes, child)
366388
nodes_by_path[child.absolute_path] = true

lua/nvim-tree/node/directory-link.lua

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@ local LinkNode = require("nvim-tree.node.link")
88
local DirectoryLinkNode = DirectoryNode:extend()
99
DirectoryLinkNode:implement(LinkNode)
1010

11-
---@param explorer Explorer
12-
---@param parent DirectoryNode
13-
---@param absolute_path string
14-
---@param link_to string
15-
---@param name string
16-
---@param fs_stat uv.fs_stat.result?
17-
---@param fs_stat_target uv.fs_stat.result
18-
function DirectoryLinkNode:new(explorer, parent, absolute_path, link_to, name, fs_stat, fs_stat_target)
19-
-- create DirectoryNode with the target path for the watcher
20-
DirectoryLinkNode.super.new(self, explorer, parent, link_to, name, fs_stat)
11+
---@class DirectoryLinkNode
12+
---@overload fun(opts: LinkNodeArgs): DirectoryLinkNode
13+
14+
---@protected
15+
---@param args LinkNodeArgs
16+
function DirectoryLinkNode:new(args)
17+
LinkNode.new(self, args)
18+
19+
-- create DirectoryNode with watcher on link_to
20+
local absolute_path = args.absolute_path
21+
args.absolute_path = args.link_to
22+
DirectoryLinkNode.super.new(self, args)
23+
24+
self.type = "link"
2125

2226
-- reset absolute path to the link itself
2327
self.absolute_path = absolute_path
24-
25-
self.type = "link"
26-
self.link_to = link_to
27-
self.fs_stat_target = fs_stat_target
2828
end
2929

3030
function DirectoryLinkNode:destroy()
@@ -76,7 +76,6 @@ end
7676
function DirectoryLinkNode:clone()
7777
local clone = DirectoryNode.clone(self) --[[@as DirectoryLinkNode]]
7878

79-
clone.type = self.type
8079
clone.link_to = self.link_to
8180
clone.fs_stat_target = self.fs_stat_target
8281

lua/nvim-tree/node/directory.lua

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,26 @@ local Node = require("nvim-tree.node")
1212
---@field private watcher Watcher?
1313
local DirectoryNode = Node:extend()
1414

15-
---@param explorer Explorer
16-
---@param parent DirectoryNode?
17-
---@param absolute_path string
18-
---@param name string
19-
---@param fs_stat uv.fs_stat.result|nil
20-
function DirectoryNode:new(explorer, parent, absolute_path, name, fs_stat)
21-
DirectoryNode.super.new(self)
22-
23-
local handle = vim.loop.fs_scandir(absolute_path)
15+
---@class DirectoryNode
16+
---@overload fun(opts: NodeArgs): DirectoryNode
17+
18+
---@protected
19+
---@param args NodeArgs
20+
function DirectoryNode:new(args)
21+
DirectoryNode.super.new(self, args)
22+
23+
local handle = vim.loop.fs_scandir(args.absolute_path)
2424
local has_children = handle and vim.loop.fs_scandir_next(handle) ~= nil or false
2525

26-
self.type = "directory"
27-
self.explorer = explorer
28-
self.absolute_path = absolute_path
29-
self.executable = false
30-
self.fs_stat = fs_stat
31-
self.git_status = nil
32-
self.hidden = false
33-
self.name = name
34-
self.parent = parent
35-
self.watcher = nil
36-
self.diag_status = nil
37-
38-
self.has_children = has_children
39-
self.group_next = nil
40-
self.nodes = {}
41-
self.open = false
42-
self.hidden_stats = nil
43-
44-
self.watcher = require("nvim-tree.explorer.watch").create_watcher(self)
26+
self.type = "directory"
27+
28+
self.has_children = has_children
29+
self.group_next = nil
30+
self.nodes = {}
31+
self.open = false
32+
self.hidden_stats = nil
33+
34+
self.watcher = require("nvim-tree.explorer.watch").create_watcher(self)
4535
end
4636

4737
function DirectoryNode:destroy()

lua/nvim-tree/node/factory.lua

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,38 @@ local Watcher = require("nvim-tree.watcher")
77
local M = {}
88

99
---Factory function to create the appropriate Node
10-
---@param explorer Explorer
11-
---@param parent DirectoryNode
12-
---@param absolute_path string
13-
---@param stat uv.fs_stat.result? -- on nil stat return nil Node
14-
---@param name string
10+
---nil on invalid stat or invalid link target stat
11+
---@param args NodeArgs
1512
---@return Node?
16-
function M.create_node(explorer, parent, absolute_path, stat, name)
17-
if not stat then
13+
function M.create(args)
14+
if not args.fs_stat then
1815
return nil
1916
end
2017

21-
if stat.type == "directory" then
18+
if args.fs_stat.type == "directory" then
2219
-- directory must be readable and enumerable
23-
if vim.loop.fs_access(absolute_path, "R") and Watcher.is_fs_event_capable(absolute_path) then
24-
return DirectoryNode(explorer, parent, absolute_path, name, stat)
20+
if vim.loop.fs_access(args.absolute_path, "R") and Watcher.is_fs_event_capable(args.absolute_path) then
21+
return DirectoryNode(args)
2522
end
26-
elseif stat.type == "file" then
27-
-- any file
28-
return FileNode(explorer, parent, absolute_path, name, stat)
29-
elseif stat.type == "link" then
23+
elseif args.fs_stat.type == "file" then
24+
return FileNode(args)
25+
elseif args.fs_stat.type == "link" then
3026
-- link target path and stat must resolve
31-
local link_to = vim.loop.fs_realpath(absolute_path)
27+
local link_to = vim.loop.fs_realpath(args.absolute_path)
3228
local link_to_stat = link_to and vim.loop.fs_stat(link_to)
3329
if not link_to or not link_to_stat then
3430
return
3531
end
3632

33+
---@cast args LinkNodeArgs
34+
args.link_to = link_to
35+
args.fs_stat_target = link_to_stat
36+
3737
-- choose directory or file
3838
if link_to_stat.type == "directory" then
39-
return DirectoryLinkNode(explorer, parent, absolute_path, link_to, name, stat, link_to_stat)
39+
return DirectoryLinkNode(args)
4040
else
41-
return FileLinkNode(explorer, parent, absolute_path, link_to, name, stat, link_to_stat)
41+
return FileLinkNode(args)
4242
end
4343
end
4444

lua/nvim-tree/node/file-link.lua

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,16 @@ local LinkNode = require("nvim-tree.node.link")
88
local FileLinkNode = FileNode:extend()
99
FileLinkNode:implement(LinkNode)
1010

11-
---@param explorer Explorer
12-
---@param parent DirectoryNode
13-
---@param absolute_path string
14-
---@param link_to string
15-
---@param name string
16-
---@param fs_stat uv.fs_stat.result?
17-
---@param fs_stat_target uv.fs_stat.result
18-
function FileLinkNode:new(explorer, parent, absolute_path, link_to, name, fs_stat, fs_stat_target)
19-
FileLinkNode.super.new(self, explorer, parent, absolute_path, name, fs_stat)
11+
---@class FileLinkNode
12+
---@overload fun(opts: LinkNodeArgs): FileLinkNode
13+
14+
---@protected
15+
---@param args LinkNodeArgs
16+
function FileLinkNode:new(args)
17+
LinkNode.new(self, args)
18+
FileLinkNode.super.new(self, args)
2019

2120
self.type = "link"
22-
self.link_to = link_to
23-
self.fs_stat_target = fs_stat_target
2421
end
2522

2623
function FileLinkNode:destroy()
@@ -65,7 +62,6 @@ end
6562
function FileLinkNode:clone()
6663
local clone = FileNode.clone(self) --[[@as FileLinkNode]]
6764

68-
clone.type = self.type
6965
clone.link_to = self.link_to
7066
clone.fs_stat_target = self.fs_stat_target
7167

lua/nvim-tree/node/file.lua

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,17 @@ local PICTURE_MAP = {
1717
---@field extension string
1818
local FileNode = Node:extend()
1919

20-
---@param explorer Explorer
21-
---@param parent DirectoryNode
22-
---@param absolute_path string
23-
---@param name string
24-
---@param fs_stat uv.fs_stat.result?
25-
function FileNode:new(explorer, parent, absolute_path, name, fs_stat)
26-
FileNode.super.new(self)
27-
28-
self.type = "file"
29-
self.explorer = explorer
30-
self.absolute_path = absolute_path
31-
self.executable = utils.is_executable(absolute_path)
32-
self.fs_stat = fs_stat
33-
self.git_status = nil
34-
self.hidden = false
35-
self.name = name
36-
self.parent = parent
37-
self.diag_status = nil
38-
39-
self.extension = string.match(name, ".?[^.]+%.(.*)") or ""
20+
---@class FileNode
21+
---@overload fun(opts: NodeArgs): FileNode
22+
23+
---@protected
24+
---@param args NodeArgs
25+
function FileNode:new(args)
26+
FileNode.super.new(self, args)
27+
28+
self.type = "file"
29+
self.extension = string.match(args.name, ".?[^.]+%.(.*)") or ""
30+
self.executable = utils.is_executable(args.absolute_path)
4031
end
4132

4233
function FileNode:destroy()

lua/nvim-tree/node/init.lua

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ local Object = require("nvim-tree.classic")
22

33
---Abstract Node class.
44
---@class (exact) Node: Object
5-
---@field type NODE_TYPE
5+
---@field type "file" | "directory" | "link" uv.fs_stat.result.type
66
---@field explorer Explorer
77
---@field absolute_path string
88
---@field executable boolean
@@ -15,8 +15,26 @@ local Object = require("nvim-tree.classic")
1515
---@field private is_dot boolean cached is_dotfile
1616
local Node = Object:extend()
1717

18-
function Node:new()
19-
self.is_dot = false
18+
---@class (exact) NodeArgs
19+
---@field explorer Explorer
20+
---@field parent DirectoryNode?
21+
---@field absolute_path string
22+
---@field name string
23+
---@field fs_stat uv.fs_stat.result?
24+
25+
---@protected
26+
---@param args NodeArgs
27+
function Node:new(args)
28+
self.explorer = args.explorer
29+
self.absolute_path = args.absolute_path
30+
self.executable = false
31+
self.fs_stat = args.fs_stat
32+
self.git_status = nil
33+
self.hidden = false
34+
self.name = args.name
35+
self.parent = args.parent
36+
self.diag_status = nil
37+
self.is_dot = false
2038
end
2139

2240
function Node:destroy()

0 commit comments

Comments
 (0)