Skip to content

Commit 3ff2ae7

Browse files
committed
feat(filesystem): add never_show_by_pattern option, closes #527
1 parent c2d282d commit 3ff2ae7

File tree

8 files changed

+86
-23
lines changed

8 files changed

+86
-23
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ use {
261261
--".DS_Store",
262262
--"thumbs.db"
263263
},
264+
never_show_by_pattern = { -- uses glob style patterns
265+
--".null-ls_*",
266+
},
264267
},
265268
follow_current_file = false, -- This will find and focus the file in the active buffer every
266269
-- time the current file is changed while the tree is open.

doc/neo-tree.txt

+7
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,9 @@ highlight group which will be applied when they are visible, see
798798
--".DS_Store",
799799
--"thumbs.db",
800800
},
801+
never_show_by_pattern = { -- uses glob style patterns
802+
--".null-ls_*",
803+
},
801804
},
802805
}
803806
})
@@ -828,6 +831,10 @@ The `never_show` option is the same as `hide_by_name`, except that those items
828831
will remain hidden even if you toggle `visible` to true. This section takes
829832
precedence over the others.
830833

834+
The `never_show_by_pattern` option is the same as `hide_by_pattern`, except that
835+
those items will remain hidden even if you toggle `visible` to true. This
836+
section takes precedence over the others.
837+
831838

832839
NETRW HIJACK BEHAVIOR *neo-tree-netrw-hijack*
833840

lua/neo-tree/defaults.lua

+3
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ local config = {
396396
--".DS_Store",
397397
--"thumbs.db"
398398
},
399+
never_show_by_pattern = { -- uses glob style patterns
400+
--".null-ls_*",
401+
},
399402
},
400403
find_by_full_path_words = false, -- `false` means it only searches the tail of a path.
401404
-- `true` will change the filter into a full path

lua/neo-tree/sources/common/file-items.lua

+8-9
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ function create_item(context, path, _type)
112112
if f.never_show[name] then
113113
item.filtered_by = item.filtered_by or {}
114114
item.filtered_by.never_show = true
115+
else
116+
if utils.is_filtered_by_pattern(f.never_show_by_pattern, path, name) then
117+
item.filtered_by = item.filtered_by or {}
118+
item.filtered_by.never_show = true
119+
end
115120
end
116121
if f.always_show[name] then
117122
item.filtered_by = item.filtered_by or {}
@@ -121,15 +126,9 @@ function create_item(context, path, _type)
121126
item.filtered_by = item.filtered_by or {}
122127
item.filtered_by.name = true
123128
end
124-
if f.hide_by_pattern then
125-
for _, p in ipairs(f.hide_by_pattern) do
126-
local separator_pattern = utils.is_windows and "\\" or "/"
127-
local match = string.find(p, separator_pattern) and path or name
128-
if string.find(match, p) then
129-
item.filtered_by = item.filtered_by or {}
130-
item.filtered_by.pattern = true
131-
end
132-
end
129+
if utils.is_filtered_by_pattern(f.hide_by_pattern, path, name) then
130+
item.filtered_by = item.filtered_by or {}
131+
item.filtered_by.pattern = true
133132
end
134133
if f.hide_dotfiles and string.sub(name, 1, 1) == "." then
135134
item.filtered_by = item.filtered_by or {}

lua/neo-tree/sources/filesystem/init.lua

+7-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ local events = require("neo-tree.events")
99
local log = require("neo-tree.log")
1010
local manager = require("neo-tree.sources.manager")
1111
local git = require("neo-tree.git")
12+
local glob = require("neo-tree.sources.filesystem.lib.globtopattern")
1213

1314
local M = { name = "filesystem" }
1415

@@ -257,12 +258,12 @@ M.setup = function(config, global_config)
257258
config.filtered_items = config.filtered_items or {}
258259
config.enable_git_status = global_config.enable_git_status
259260

260-
local hide_by_pattern = config.filtered_items.hide_by_pattern
261-
if hide_by_pattern then
262-
local glob = require("neo-tree.sources.filesystem.lib.globtopattern")
263-
for i, pattern in ipairs(hide_by_pattern) do
264-
hide_by_pattern[i] = glob.globtopattern(pattern)
265-
log.trace("hide_by_pattern: ", pattern, " -> ", hide_by_pattern[i])
261+
for _, key in ipairs({ "hide_by_pattern", "never_show_by_pattern" }) do
262+
local list = config.filtered_items[key]
263+
if type(list) == "table" then
264+
for i, pattern in ipairs(list) do
265+
list[i] = glob.globtopattern(pattern)
266+
end
266267
end
267268
end
268269

lua/neo-tree/sources/filesystem/lib/fs_scan.lua

+33-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ local file_items = require("neo-tree.sources.common.file-items")
88
local log = require("neo-tree.log")
99
local fs_watch = require("neo-tree.sources.filesystem.lib.fs_watch")
1010
local git = require("neo-tree.git")
11+
local events = require("neo-tree.events")
1112

1213
local Path = require("plenary.path")
1314
local os_sep = Path.path.sep
@@ -23,13 +24,22 @@ local on_directory_loaded = function(context, dir_path)
2324
if state.use_libuv_file_watcher then
2425
local root = context.folders[dir_path]
2526
if root then
26-
if root.is_link then
27-
log.trace("Adding fs watcher for ", root.link_to)
28-
fs_watch.watch_folder(root.link_to)
29-
else
30-
log.trace("Adding fs watcher for ", root.path)
31-
fs_watch.watch_folder(root.path)
32-
end
27+
local target_path = root.is_link and root.link_to or root.path
28+
local fs_watch_callback = vim.schedule_wrap(function(err, fname)
29+
if err then
30+
log.error("file_event_callback: ", err)
31+
return
32+
end
33+
if context.is_a_never_show_file(fname) then
34+
-- don't fire events for nodes that are designated as "never show"
35+
return
36+
else
37+
events.fire_event(events.FS_EVENT, { afile = target_path })
38+
end
39+
end)
40+
41+
log.trace("Adding fs watcher for ", target_path)
42+
fs_watch.watch_folder(target_path, fs_watch_callback)
3343
end
3444
end
3545
end
@@ -290,6 +300,22 @@ M.get_items = function(state, parent_id, path_to_reveal, callback, async, recurs
290300
context.paths_to_load = utils.unique(context.paths_to_load)
291301
end
292302
end
303+
304+
local filtered_items = state.filtered_items or {}
305+
context.is_a_never_show_file = function(fname)
306+
if fname then
307+
local _, name = utils.split_path(fname)
308+
if name then
309+
if filtered_items.never_show and filtered_items.never_show[name] then
310+
return true
311+
end
312+
if utils.is_filtered_by_pattern(filtered_items.never_show_by_pattern, fname, name) then
313+
return true
314+
end
315+
end
316+
end
317+
return false
318+
end
293319
if async then
294320
async_scan(context, path)
295321
else

lua/neo-tree/sources/filesystem/lib/fs_watch.lua

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ end
3636

3737
---Watch a directory for changes to it's children. Not recursive.
3838
---@param path string The directory to watch.
39+
---@param custom_callback? function The callback to call when a change is detected.
40+
---@param allow_git_watch? boolean Allow watching of git folders.
3941
M.watch_folder = function(path, custom_callback, allow_git_watch)
4042
if not allow_git_watch then
4143
if path:find("/%.git$") or path:find("/%.git/") then
@@ -49,7 +51,7 @@ M.watch_folder = function(path, custom_callback, allow_git_watch)
4951
log.trace("Starting new fs watch on: ", path)
5052
local callback = custom_callback
5153
or vim.schedule_wrap(function(err, fname)
52-
if fname and fname:match("^%._null-ls_.+") then
54+
if fname and fname:match("^%.null[-]ls_.+") then
5355
-- null-ls temp file: https://github.com/jose-elias-alvarez/null-ls.nvim/pull/1075
5456
return
5557
end

lua/neo-tree/utils.lua

+22
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,28 @@ M.group_by = function(array, key)
322322
return result
323323
end
324324

325+
---Determines if a file should be filtered by a given list of glob patterns.
326+
---@param pattern_list table The list of glob patterns to filter by.
327+
---@param path string The full path to the file.
328+
---@param name string|nil The name of the file.
329+
---@return boolean
330+
M.is_filtered_by_pattern = function(pattern_list, path, name)
331+
if pattern_list == nil then
332+
return false
333+
end
334+
if name == nil then
335+
_, name = M.split_path(path)
336+
end
337+
for _, p in ipairs(pattern_list) do
338+
local separator_pattern = M.is_windows and "\\" or "/"
339+
local filename = string.find(p, separator_pattern) and path or name
340+
if string.find(filename, p) then
341+
return true
342+
end
343+
end
344+
return false
345+
end
346+
325347
M.is_floating = function(win_id)
326348
win_id = win_id or vim.api.nvim_get_current_win()
327349
local cfg = vim.api.nvim_win_get_config(win_id)

0 commit comments

Comments
 (0)