@@ -15,45 +15,90 @@ local DecoratorOpened = require "nvim-tree.renderer.decorator.opened"
15
15
local pad = require " nvim-tree.renderer.components.padding"
16
16
local icons = require " nvim-tree.renderer.components.icons"
17
17
18
- local M = {
19
- opts = {},
20
- decorators = {},
21
- picture_map = {
22
- jpg = true ,
23
- jpeg = true ,
24
- png = true ,
25
- gif = true ,
26
- webp = true ,
27
- jxl = true ,
28
- },
18
+ local PICTURE_MAP = {
19
+ jpg = true ,
20
+ jpeg = true ,
21
+ png = true ,
22
+ gif = true ,
23
+ webp = true ,
24
+ jxl = true ,
29
25
}
30
26
31
- --- @class HighlightedString
27
+ --- @class ( exact ) HighlightedString
32
28
--- @field str string
33
29
--- @field hl string[]
34
30
35
- --- @class AddHighlightArgs
31
+ --- @class ( exact ) AddHighlightArgs
36
32
--- @field group string[]
37
33
--- @field line number
38
34
--- @field col_start number
39
35
--- @field col_end number
40
36
41
- --- @class Builder
37
+ --- @class ( exact ) Builder
42
38
--- @field lines string[] includes icons etc.
43
39
--- @field hl_args AddHighlightArgs[] line highlights
44
40
--- @field signs string[] line signs
45
41
--- @field extmarks table[] extra marks for right icon placement
46
42
--- @field virtual_lines table[] virtual lines for hidden count display
47
- --- @field private root_cwd string absolute path
43
+ --- @field private explorer Explorer
44
+ --- @field private root_cwd string | nil absolute path
48
45
--- @field private index number
49
46
--- @field private depth number
50
47
--- @field private combined_groups table<string , boolean> combined group names
51
48
--- @field private markers boolean[] indent markers
49
+ --- @field private decorators Decorator[]
50
+ --- @field private hidden_display fun (node : Node ): string | nil
52
51
local Builder = {}
53
52
53
+ --- @param opts table
54
+ --- @return fun ( node : Node ): string | nil
55
+ local setup_hidden_display_function = function (opts )
56
+ local hidden_display = opts .renderer .hidden_display
57
+ -- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then
58
+ if type (hidden_display ) == " string" then
59
+ if hidden_display == " none" then
60
+ return function ()
61
+ return nil
62
+ end
63
+ elseif hidden_display == " simple" then
64
+ return function (hidden_stats )
65
+ return utils .default_format_hidden_count (hidden_stats , true )
66
+ end
67
+ else -- "all"
68
+ return function (hidden_stats )
69
+ return utils .default_format_hidden_count (hidden_stats , false )
70
+ end
71
+ end
72
+ else -- "function
73
+ return function (hidden_stats )
74
+ -- In case of missing field such as live_filter we zero it, otherwise keep field as is
75
+ hidden_stats = vim .tbl_deep_extend (" force" , {
76
+ live_filter = 0 ,
77
+ git = 0 ,
78
+ buf = 0 ,
79
+ dotfile = 0 ,
80
+ custom = 0 ,
81
+ bookmark = 0 ,
82
+ }, hidden_stats or {})
83
+
84
+ local ok , result = pcall (hidden_display , hidden_stats )
85
+ if not ok then
86
+ notify .warn " Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree"
87
+ return nil
88
+ end
89
+ return result
90
+ end
91
+ end
92
+ end
93
+
94
+ --- @param opts table user options
95
+ --- @param explorer Explorer
54
96
--- @return Builder
55
- function Builder :new ()
97
+ function Builder :new (opts , explorer )
98
+ --- @type Builder
56
99
local o = {
100
+ opts = opts ,
101
+ explorer = explorer ,
57
102
root_cwd = core .get_cwd (),
58
103
index = 0 ,
59
104
depth = 0 ,
@@ -64,9 +109,21 @@ function Builder:new()
64
109
signs = {},
65
110
extmarks = {},
66
111
virtual_lines = {},
112
+ decorators = {
113
+ -- priority order
114
+ DecoratorCut :new (opts ),
115
+ DecoratorCopied :new (opts ),
116
+ DecoratorDiagnostics :new (opts ),
117
+ DecoratorBookmarks :new (opts ),
118
+ DecoratorModified :new (opts ),
119
+ DecoratorHidden :new (opts ),
120
+ DecoratorOpened :new (opts ),
121
+ DecoratorGit :new (opts ),
122
+ },
123
+ hidden_display = setup_hidden_display_function (opts ),
67
124
}
68
- setmetatable ( o , self )
69
- self . __index = self
125
+
126
+ setmetatable ( o , { __index = self })
70
127
71
128
return o
72
129
end
@@ -89,16 +146,16 @@ function Builder:get_folder_name(node)
89
146
next = next .group_next
90
147
end
91
148
92
- if node .group_next and type (M .opts .renderer .group_empty ) == " function" then
93
- local new_name = M .opts .renderer .group_empty (name )
149
+ if node .group_next and type (self .opts .renderer .group_empty ) == " function" then
150
+ local new_name = self .opts .renderer .group_empty (name )
94
151
if type (new_name ) == " string" then
95
152
name = new_name
96
153
else
97
154
notify .warn (string.format (" Invalid return type for field renderer.group_empty. Expected string, got %s" , type (new_name )))
98
155
end
99
156
end
100
157
101
- return string.format (" %s%s" , name , M .opts .renderer .add_trailing and " /" or " " )
158
+ return string.format (" %s%s" , name , self .opts .renderer .add_trailing and " /" or " " )
102
159
end
103
160
104
161
--- @private
@@ -139,13 +196,13 @@ function Builder:build_folder(node)
139
196
end
140
197
141
198
local foldername_hl = " NvimTreeFolderName"
142
- if node .link_to and M .opts .renderer .symlink_destination then
199
+ if node .link_to and self .opts .renderer .symlink_destination then
143
200
local arrow = icons .i .symlink_arrow
144
201
local link_to = utils .path_relative (node .link_to , self .root_cwd )
145
202
foldername = string.format (" %s%s%s" , foldername , arrow , link_to )
146
203
foldername_hl = " NvimTreeSymlinkFolderName"
147
204
elseif
148
- vim .tbl_contains (M .opts .renderer .special_files , node .absolute_path ) or vim .tbl_contains (M .opts .renderer .special_files , node .name )
205
+ vim .tbl_contains (self .opts .renderer .special_files , node .absolute_path ) or vim .tbl_contains (self .opts .renderer .special_files , node .name )
149
206
then
150
207
foldername_hl = " NvimTreeSpecialFolderName"
151
208
elseif node .open then
@@ -165,7 +222,7 @@ function Builder:build_symlink(node)
165
222
local icon = icons .i .symlink
166
223
local arrow = icons .i .symlink_arrow
167
224
local symlink_formatted = node .name
168
- if M .opts .renderer .symlink_destination then
225
+ if self .opts .renderer .symlink_destination then
169
226
local link_to = utils .path_relative (node .link_to , self .root_cwd )
170
227
symlink_formatted = string.format (" %s%s%s" , symlink_formatted , arrow , link_to )
171
228
end
@@ -179,11 +236,13 @@ end
179
236
--- @return HighlightedString name
180
237
function Builder :build_file (node )
181
238
local hl
182
- if vim .tbl_contains (M .opts .renderer .special_files , node .absolute_path ) or vim .tbl_contains (M .opts .renderer .special_files , node .name ) then
239
+ if
240
+ vim .tbl_contains (self .opts .renderer .special_files , node .absolute_path ) or vim .tbl_contains (self .opts .renderer .special_files , node .name )
241
+ then
183
242
hl = " NvimTreeSpecialFile"
184
243
elseif node .executable then
185
244
hl = " NvimTreeExecFile"
186
- elseif M . picture_map [node .extension ] then
245
+ elseif PICTURE_MAP [node .extension ] then
187
246
hl = " NvimTreeImageFile"
188
247
end
189
248
@@ -206,7 +265,7 @@ function Builder:format_line(indent_markers, arrows, icon, name, node)
206
265
end
207
266
for _ , v in ipairs (t2 ) do
208
267
if added_len > 0 then
209
- table.insert (t1 , { str = M .opts .renderer .icons .padding })
268
+ table.insert (t1 , { str = self .opts .renderer .icons .padding })
210
269
end
211
270
table.insert (t1 , v )
212
271
end
@@ -222,19 +281,19 @@ function Builder:format_line(indent_markers, arrows, icon, name, node)
222
281
local line = { indent_markers , arrows }
223
282
add_to_end (line , { icon })
224
283
225
- for i = # M .decorators , 1 , - 1 do
226
- add_to_end (line , M .decorators [i ]:icons_before (node ))
284
+ for i = # self .decorators , 1 , - 1 do
285
+ add_to_end (line , self .decorators [i ]:icons_before (node ))
227
286
end
228
287
229
288
add_to_end (line , { name })
230
289
231
- for i = # M .decorators , 1 , - 1 do
232
- add_to_end (line , M .decorators [i ]:icons_after (node ))
290
+ for i = # self .decorators , 1 , - 1 do
291
+ add_to_end (line , self .decorators [i ]:icons_after (node ))
233
292
end
234
293
235
294
local rights = {}
236
- for i = # M .decorators , 1 , - 1 do
237
- add_to_end (rights , M .decorators [i ]:icons_right_align (node ))
295
+ for i = # self .decorators , 1 , - 1 do
296
+ add_to_end (rights , self .decorators [i ]:icons_right_align (node ))
238
297
end
239
298
if # rights > 0 then
240
299
self .extmarks [self .index ] = rights
248
307
function Builder :build_signs (node )
249
308
-- first in priority order
250
309
local sign_name
251
- for _ , d in ipairs (M .decorators ) do
310
+ for _ , d in ipairs (self .decorators ) do
252
311
sign_name = d :sign_name (node )
253
312
if sign_name then
254
313
self .signs [self .index ] = sign_name
@@ -300,8 +359,8 @@ function Builder:add_highlights(node)
300
359
local icon_groups = {}
301
360
local name_groups = {}
302
361
local d , icon , name
303
- for i = # M .decorators , 1 , - 1 do
304
- d = M .decorators [i ]
362
+ for i = # self .decorators , 1 , - 1 do
363
+ d = self .decorators [i ]
305
364
icon , name = d :groups_icon_name (node )
306
365
table.insert (icon_groups , icon )
307
366
table.insert (name_groups , name )
@@ -366,10 +425,10 @@ function Builder:add_hidden_count_string(node, idx, num_children)
366
425
if not node .open then
367
426
return
368
427
end
369
- local hidden_count_string = M . opts . renderer .hidden_display (node .hidden_stats )
428
+ local hidden_count_string = self .hidden_display (node .hidden_stats )
370
429
if hidden_count_string and hidden_count_string ~= " " then
371
430
local indent_markers = pad .get_indent_markers (self .depth , idx or 0 , num_children or 0 , node , self .markers , 1 )
372
- local indent_width = M .opts .renderer .indent_width
431
+ local indent_width = self .opts .renderer .indent_width
373
432
374
433
local indent_padding = string.rep (" " , indent_width )
375
434
local indent_string = indent_padding .. indent_markers .str
@@ -438,16 +497,16 @@ end
438
497
function Builder :build_header ()
439
498
local explorer = core .get_explorer ()
440
499
if view .is_root_folder_visible (core .get_cwd ()) then
441
- local root_name = self :format_root_name (M .opts .renderer .root_folder_label )
500
+ local root_name = self :format_root_name (self .opts .renderer .root_folder_label )
442
501
table.insert (self .lines , root_name )
443
502
self :insert_highlight ({ " NvimTreeRootFolder" }, 0 , string.len (root_name ))
444
503
self .index = 1
445
504
end
446
505
447
506
if explorer and explorer .live_filter .filter then
448
- local filter_line = string.format (" %s/%s/" , M .opts .live_filter .prefix , explorer .live_filter .filter )
507
+ local filter_line = string.format (" %s/%s/" , self .opts .live_filter .prefix , explorer .live_filter .filter )
449
508
table.insert (self .lines , filter_line )
450
- local prefix_length = string.len (M .opts .live_filter .prefix )
509
+ local prefix_length = string.len (self .opts .live_filter .prefix )
451
510
self :insert_highlight ({ " NvimTreeLiveFilterPrefix" }, 0 , prefix_length )
452
511
self :insert_highlight ({ " NvimTreeLiveFilterValue" }, prefix_length , string.len (filter_line ))
453
512
self .index = self .index + 1
@@ -472,63 +531,4 @@ function Builder:build()
472
531
return self
473
532
end
474
533
475
- --- @param opts table
476
- local setup_hidden_display_function = function (opts )
477
- local hidden_display = opts .renderer .hidden_display
478
- -- options are already validated, so ´hidden_display´ can ONLY be `string` or `function` if type(hidden_display) == "string" then
479
- if type (hidden_display ) == " string" then
480
- if hidden_display == " none" then
481
- opts .renderer .hidden_display = function ()
482
- return nil
483
- end
484
- elseif hidden_display == " simple" then
485
- opts .renderer .hidden_display = function (hidden_stats )
486
- return utils .default_format_hidden_count (hidden_stats , true )
487
- end
488
- elseif hidden_display == " all" then
489
- opts .renderer .hidden_display = function (hidden_stats )
490
- return utils .default_format_hidden_count (hidden_stats , false )
491
- end
492
- end
493
- elseif type (hidden_display ) == " function" then
494
- local safe_render = function (hidden_stats )
495
- -- In case of missing field such as live_filter we zero it, otherwise keep field as is
496
- hidden_stats = vim .tbl_deep_extend (" force" , {
497
- live_filter = 0 ,
498
- git = 0 ,
499
- buf = 0 ,
500
- dotfile = 0 ,
501
- custom = 0 ,
502
- bookmark = 0 ,
503
- }, hidden_stats or {})
504
-
505
- local ok , result = pcall (hidden_display , hidden_stats )
506
- if not ok then
507
- notify .warn " Problem occurred in the function ``opts.renderer.hidden_display`` see nvim-tree.renderer.hidden_display on :h nvim-tree"
508
- return nil
509
- end
510
- return result
511
- end
512
-
513
- opts .renderer .hidden_display = safe_render
514
- end
515
- end
516
-
517
- function Builder .setup (opts )
518
- setup_hidden_display_function (opts )
519
- M .opts = opts
520
-
521
- -- priority order
522
- M .decorators = {
523
- DecoratorCut :new (opts ),
524
- DecoratorCopied :new (opts ),
525
- DecoratorDiagnostics :new (opts ),
526
- DecoratorBookmarks :new (opts ),
527
- DecoratorModified :new (opts ),
528
- DecoratorHidden :new (opts ),
529
- DecoratorOpened :new (opts ),
530
- DecoratorGit :new (opts ),
531
- }
532
- end
533
-
534
534
return Builder
0 commit comments