Skip to content

Commit 9053a6d

Browse files
committed
feat(hidden_display): update defaults in Builder to allow rendering
1 parent c41c752 commit 9053a6d

File tree

12 files changed

+333
-45
lines changed

12 files changed

+333
-45
lines changed

doc/nvim-tree-lua.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ Following is the default configuration. See |nvim-tree-opts| for details.
423423
root_folder_label = ":~:s?$?/..?",
424424
indent_width = 2,
425425
special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
426+
hidden_display_function = nil,
426427
symlink_destination = true,
427428
highlight_git = "none",
428429
highlight_diagnostics = "none",
@@ -878,6 +879,46 @@ Number of spaces for an each tree nesting level. Minimum 1.
878879
A list of filenames that gets highlighted with `NvimTreeSpecialFile`.
879880
Type: `table`, Default: `{ "Cargo.toml", "Makefile", "README.md", "readme.md", }`
880881

882+
*nvim-tree.renderer.hidden_display_function
883+
Determines the rendering of hidden files in a folder.
884+
Type: function | string, Default: "none"
885+
Possible string values are:
886+
- "none": Doesn't inform anything about hidden files.
887+
- "simple": Shows how many hidden files are in a folder.
888+
- "all": Shows how many files are hidden and the number of hidden files per reason why they're hidden.
889+
890+
Example "all":
891+
If a folder has 14 hidden items for various reasons, the display might show:
892+
``(14 total git: 5, dotfile: 9)``.
893+
894+
If a function is provided, it receives a table `hidden_count` where keys are reasons and values are the count of hidden files for that reason.
895+
The `hidden_count` argument is structured as follows, where <num> is the number
896+
of hidden files related to the field.
897+
898+
hidden_count = {
899+
bookmark = <num>,
900+
buf = <num>,
901+
custom = <num>,
902+
dotfile = <num>,
903+
git = <num>,
904+
live_filter = <num>,
905+
}
906+
907+
Example of function that can be passed:
908+
909+
function(hidden_count)
910+
local total_count = 0
911+
for reason, count in pairs(hidden_count) do
912+
total_count = total_count + count
913+
end
914+
915+
if total_count > 0 then
916+
return "(" .. tostring(total_count) .. " hidden")"
917+
end
918+
return nil
919+
end
920+
921+
881922
*nvim-tree.renderer.symlink_destination*
882923
Whether to show the destination of the symlink.
883924
Type: `boolean`, Default: `true`
@@ -2901,6 +2942,7 @@ highlight group is not, hard linking as follows: >
29012942
|nvim-tree.renderer.icons.glyphs.modified|
29022943
|nvim-tree.renderer.icons.glyphs.symlink|
29032944
|nvim-tree.renderer.icons.hidden_placement|
2945+
|nvim-tree.renderer.icons.hidden_placement|
29042946
|nvim-tree.renderer.icons.modified_placement|
29052947
|nvim-tree.renderer.icons.padding|
29062948
|nvim-tree.renderer.icons.show|

lua/nvim-tree.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
387387
root_folder_label = ":~:s?$?/..?",
388388
indent_width = 2,
389389
special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
390+
hidden_display_function = "none",
390391
symlink_destination = true,
391392
highlight_git = "none",
392393
highlight_diagnostics = "none",
@@ -636,6 +637,7 @@ local ACCEPTED_TYPES = {
636637
},
637638
},
638639
renderer = {
640+
hidden_display_function = { "function", "string" },
639641
group_empty = { "boolean", "function" },
640642
root_folder_label = { "function", "string", "boolean" },
641643
},
@@ -669,6 +671,7 @@ local ACCEPTED_STRINGS = {
669671
signcolumn = { "yes", "no", "auto" },
670672
},
671673
renderer = {
674+
hidden_display_function = { "none", "simple", "all" },
672675
highlight_git = { "none", "icon", "name", "all" },
673676
highlight_opened_files = { "none", "icon", "name", "all" },
674677
highlight_modified = { "none", "icon", "name", "all" },

lua/nvim-tree/appearance/init.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ M.HIGHLIGHT_GROUPS = {
8282
{ group = "NvimTreeHiddenFileHL", link = "NvimTreeHiddenIcon" },
8383
{ group = "NvimTreeHiddenFolderHL", link = "NvimTreeHiddenFileHL" },
8484

85+
-- Hidden Display
86+
{ group = "NvimTreeHiddenDisplay", link = "Conceal" },
87+
8588
-- Opened
8689
{ group = "NvimTreeOpenedHL", link = "Special" },
8790

lua/nvim-tree/explorer/explore.lua

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ local sorters = require "nvim-tree.explorer.sorters"
66
local filters = require "nvim-tree.explorer.filters"
77
local live_filter = require "nvim-tree.live-filter"
88
local log = require "nvim-tree.log"
9+
-- local explorer_module = require "nvim-tree.explorer"
910

11+
local FILTER_REASON = filters.FILTER_REASON
1012
local Watcher = require "nvim-tree.watcher"
1113

1214
local M = {}
@@ -21,21 +23,31 @@ local function populate_children(handle, cwd, node, git_status)
2123
local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
2224

2325
local filter_status = filters.prepare(git_status)
26+
27+
node.hidden_count = vim.tbl_deep_extend("force", node.hidden_count or {}, {
28+
git = 0,
29+
buf = 0,
30+
dotfile = 0,
31+
custom = 0,
32+
bookmark = 0,
33+
})
34+
2435
while true do
2536
local name, t = vim.loop.fs_scandir_next(handle)
2637
if not name then
2738
break
2839
end
40+
local is_dir = t == "directory"
2941

3042
local abs = utils.path_join { cwd, name }
3143
local profile = log.profile_start("explore populate_children %s", abs)
3244

3345
---@type uv.fs_stat.result|nil
3446
local stat = vim.loop.fs_stat(abs)
35-
36-
if not filters.should_filter(abs, stat, filter_status) and not nodes_by_path[abs] and Watcher.is_fs_event_capable(abs) then
47+
local filter_reason = filters.should_filter_as_reason(abs, stat, filter_status)
48+
if filter_reason == FILTER_REASON.none and not nodes_by_path[abs] and Watcher.is_fs_event_capable(abs) then
3749
local child = nil
38-
if t == "directory" and vim.loop.fs_access(abs, "R") then
50+
if is_dir and vim.loop.fs_access(abs, "R") then
3951
child = builders.folder(node, abs, name, stat)
4052
elseif t == "file" then
4153
child = builders.file(node, abs, name, stat)
@@ -50,10 +62,18 @@ local function populate_children(handle, cwd, node, git_status)
5062
nodes_by_path[child.absolute_path] = true
5163
explorer_node.update_git_status(child, node_ignored, git_status)
5264
end
65+
else
66+
for reason, value in pairs(FILTER_REASON) do
67+
if filter_reason == value then
68+
node.hidden_count[reason] = node.hidden_count[reason] + 1
69+
end
70+
end
5371
end
5472

5573
log.profile_end(profile)
5674
end
75+
76+
-- explorer_module.reload(node)
5777
end
5878

5979
---@param node Node
@@ -70,13 +90,6 @@ function M.explore(node, status)
7090

7191
populate_children(handle, cwd, node, status)
7292

73-
local child_hidden_count = 0
74-
for _, child_node in ipairs(node.nodes) do
75-
if child_node then
76-
child_hidden_count = child_hidden_count + 1
77-
end
78-
end
79-
8093
local is_root = not node.parent
8194
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
8295
if M.config.group_empty and not is_root and child_folder_only then
@@ -89,26 +102,13 @@ function M.explore(node, status)
89102
log.profile_end(profile)
90103
return ns
91104
end
92-
105+
local old_num = #node.nodes
93106
sorters.sort(node.nodes)
94107
live_filter.apply_filter(node)
95108

96-
if true or child_hidden_count ~= 0 then
97-
table.insert(node.nodes, {
98-
absolute_path = "",
99-
git_status = {},
100-
101-
has_children = false,
102-
name = "(" .. tostring(child_hidden_count) .. " hidden items)",
103-
nodes = {},
104-
open = false,
105-
106-
parent = node,
107-
type = "file",
108-
})
109-
end
110-
111109
log.profile_end(profile)
110+
local new_num = #node.nodes
111+
assert(old_num == new_num, vim.inspect { old_num = old_num, new_num = new_num })
112112
return node.nodes
113113
end
114114

lua/nvim-tree/explorer/filters.lua

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,19 @@ local M = {
66
custom_function = nil,
77
}
88

9+
---@enum FILTER_REASON
10+
M.FILTER_REASON = {
11+
none = 0, -- It's not filtered
12+
git = 1,
13+
buf = 2,
14+
dotfile = 4,
15+
custom = 8,
16+
bookmark = 16,
17+
}
18+
919
---@param path string
1020
---@return boolean
11-
local function is_excluded(path)
21+
M.is_excluded = function(path)
1222
for _, node in ipairs(M.exclude_list) do
1323
if path:match(node) then
1424
return true
@@ -21,7 +31,7 @@ end
2131
---@param path string Absolute path
2232
---@param git_status table from prepare
2333
---@return boolean
24-
local function git(path, git_status)
34+
M.git = function(path, git_status)
2535
if type(git_status) ~= "table" or type(git_status.files) ~= "table" or type(git_status.dirs) ~= "table" then
2636
return false
2737
end
@@ -48,7 +58,7 @@ end
4858
---@param path string Absolute path
4959
---@param bufinfo table vim.fn.getbufinfo { buflisted = 1 }
5060
---@return boolean
51-
local function buf(path, bufinfo)
61+
M.buf = function(path, bufinfo)
5262
if not M.config.filter_no_buffer or type(bufinfo) ~= "table" then
5363
return false
5464
end
@@ -65,14 +75,14 @@ end
6575

6676
---@param path string
6777
---@return boolean
68-
local function dotfile(path)
78+
M.dotfile = function(path)
6979
return M.config.filter_dotfiles and utils.path_basename(path):sub(1, 1) == "."
7080
end
7181

7282
---@param path string
7383
---@param path_type string|nil filetype of path
7484
---@param bookmarks table<string, string|nil> path, filetype table of bookmarked files
75-
local function bookmark(path, path_type, bookmarks)
85+
M.bookmark = function(path, path_type, bookmarks)
7686
if not M.config.filter_no_bookmark then
7787
return false
7888
end
@@ -107,7 +117,7 @@ end
107117

108118
---@param path string
109119
---@return boolean
110-
local function custom(path)
120+
M.custom = function(path)
111121
if not M.config.filter_custom then
112122
return false
113123
end
@@ -175,15 +185,44 @@ function M.should_filter(path, fs_stat, status)
175185
end
176186

177187
-- exclusions override all filters
178-
if is_excluded(path) then
188+
if M.is_excluded(path) then
179189
return false
180190
end
181191

182-
return git(path, status.git_status)
183-
or buf(path, status.bufinfo)
184-
or dotfile(path)
185-
or custom(path)
186-
or bookmark(path, fs_stat and fs_stat.type, status.bookmarks)
192+
return M.git(path, status.git_status)
193+
or M.buf(path, status.bufinfo)
194+
or M.dotfile(path)
195+
or M.custom(path)
196+
or M.bookmark(path, fs_stat and fs_stat.type, status.bookmarks)
197+
end
198+
199+
---@param path string Absolute path
200+
---@param fs_stat uv.fs_stat.result|nil fs_stat of file
201+
---@param status table from prepare
202+
---@return FILTER_REASON
203+
function M.should_filter_as_reason(path, fs_stat, status)
204+
if not M.config.enable then
205+
return M.FILTER_REASON.none
206+
end
207+
208+
-- exclusions override all filters
209+
if M.is_excluded(path) then
210+
return M.FILTER_REASON.none
211+
end
212+
213+
if M.git(path, status.git_status) then
214+
return M.FILTER_REASON.git
215+
elseif M.buf(path, status.bufinfo) then
216+
return M.FILTER_REASON.buf
217+
elseif M.dotfile(path) then
218+
return M.FILTER_REASON.dotfile
219+
elseif M.custom(path) then
220+
return M.FILTER_REASON.custom
221+
elseif M.bookmark(path, fs_stat and fs_stat.type, status.bookmarks) then
222+
return M.FILTER_REASON.bookmark
223+
else
224+
return M.FILTER_REASON.none
225+
end
187226
end
188227

189228
function M.setup(opts)

lua/nvim-tree/explorer/reload.lua

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ local live_filter = require "nvim-tree.live-filter"
77
local git = require "nvim-tree.git"
88
local log = require "nvim-tree.log"
99

10+
local FILTER_REASON = filters.FILTER_REASON
1011
local NodeIterator = require "nvim-tree.iterators.node-iterator"
1112
local Watcher = require "nvim-tree.watcher"
1213

@@ -79,6 +80,7 @@ function M.reload(node, git_status)
7980
local profile = log.profile_start("reload %s", node.absolute_path)
8081

8182
local filter_status = filters.prepare(git_status)
83+
local is_dir = node.type == "directory"
8284

8385
if node.group_next then
8486
node.nodes = { node.group_next }
@@ -90,6 +92,16 @@ function M.reload(node, git_status)
9092
local node_ignored = explorer_node.is_git_ignored(node)
9193
---@type table<string, Node>
9294
local nodes_by_path = utils.key_by(node.nodes, "absolute_path")
95+
96+
-- To reset we must 'zero' everything that we use
97+
node.hidden_count = vim.tbl_deep_extend("force", node.hidden_count or {}, {
98+
git = 0,
99+
buf = 0,
100+
dotfile = 0,
101+
custom = 0,
102+
bookmark = 0,
103+
})
104+
93105
while true do
94106
local name, t = vim.loop.fs_scandir_next(handle)
95107
if not name then
@@ -100,7 +112,8 @@ function M.reload(node, git_status)
100112
---@type uv.fs_stat.result|nil
101113
local stat = vim.loop.fs_stat(abs)
102114

103-
if not filters.should_filter(abs, stat, filter_status) then
115+
local filter_reason = filters.should_filter_as_reason(abs, stat, filter_status)
116+
if filter_reason == FILTER_REASON.none then
104117
remain_childs[abs] = true
105118

106119
-- Recreate node if type changes.
@@ -137,6 +150,12 @@ function M.reload(node, git_status)
137150
n.fs_stat = stat
138151
end
139152
end
153+
else
154+
for reason, value in pairs(FILTER_REASON) do
155+
if filter_reason == value then
156+
node.hidden_count[reason] = node.hidden_count[reason] + 1
157+
end
158+
end
140159
end
141160
end
142161

lua/nvim-tree/lib.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ local utils = require "nvim-tree.utils"
55
local events = require "nvim-tree.events"
66
local notify = require "nvim-tree.notify"
77
local explorer_node = require "nvim-tree.explorer.node"
8+
local actions_reloaders = require "nvim-tree.actions.reloaders"
89

910
---@class LibOpenOpts
1011
---@field path string|nil path
@@ -146,6 +147,10 @@ function M.expand_or_collapse(node, toggle_group)
146147
if node.has_children then
147148
node.has_children = false
148149
end
150+
-- TODO: Inspect(node)
151+
152+
-- node.hidden_count = utils.count_hidden_files(node.absolute_path)
153+
-- node.hidden_count = 79
149154

150155
if #node.nodes == 0 then
151156
core.get_explorer():expand(node)

0 commit comments

Comments
 (0)