feat(view): add filters.git_clean, filters.no_buffer (#1784)
* feat(view): add filters.git_clean * feat(view): add filters.git_clean * feat(view): add filters.no_buffer * feat(view): filters.no_buffer misses unloaded, handles buffer in/out * feat(view): filters.no_buffer matches directories specifically * feat(view): filters.no_buffer clarify targets * feat: add placeholder filters.diagnostics_ok, refactor filters * feat(view): remove placeholder filters.diagnostics_ok
This commit is contained in:
committed by
GitHub
parent
e49fa4e529
commit
c5dc80c36b
@@ -296,7 +296,7 @@ Subsequent calls to setup will replace the previous configuration.
|
|||||||
debounce_delay = 50,
|
debounce_delay = 50,
|
||||||
severity = {
|
severity = {
|
||||||
min = vim.diagnostic.severity.HINT,
|
min = vim.diagnostic.severity.HINT,
|
||||||
max = vim.diagnostic.severity.ERROR
|
max = vim.diagnostic.severity.ERROR,
|
||||||
},
|
},
|
||||||
icons = {
|
icons = {
|
||||||
hint = "",
|
hint = "",
|
||||||
@@ -307,6 +307,8 @@ Subsequent calls to setup will replace the previous configuration.
|
|||||||
},
|
},
|
||||||
filters = {
|
filters = {
|
||||||
dotfiles = false,
|
dotfiles = false,
|
||||||
|
git_clean = false,
|
||||||
|
no_buffer = false,
|
||||||
custom = {},
|
custom = {},
|
||||||
exclude = {},
|
exclude = {},
|
||||||
},
|
},
|
||||||
@@ -903,6 +905,19 @@ Filtering options.
|
|||||||
Toggle via the `toggle_dotfiles` action, default mapping `H`.
|
Toggle via the `toggle_dotfiles` action, default mapping `H`.
|
||||||
Type: `boolean`, Default: `false`
|
Type: `boolean`, Default: `false`
|
||||||
|
|
||||||
|
*nvim-tree.filters.git_clean*
|
||||||
|
Do not show files with no git status. This will show ignored files when
|
||||||
|
|nvim-tree.git.ignore| is set, as they are effectively dirty.
|
||||||
|
Toggle via the `toggle_git_clean` action, default mapping `C`.
|
||||||
|
Type: `boolean`, Default: `false`
|
||||||
|
|
||||||
|
*nvim-tree.filters.no_buffer*
|
||||||
|
Do not show files that have no listed buffer.
|
||||||
|
Toggle via the `toggle_no_buffer` action, default mapping `B`.
|
||||||
|
For performance reasons this may not immediately update on buffer
|
||||||
|
delete/wipe. A reload or filesystem event will result in an update.
|
||||||
|
Type: `boolean`, Default: `false`
|
||||||
|
|
||||||
*nvim-tree.filters.custom*
|
*nvim-tree.filters.custom*
|
||||||
Custom list of vim regex for file/directory names that will not be shown.
|
Custom list of vim regex for file/directory names that will not be shown.
|
||||||
Backslashes must be escaped e.g. "^\\.git". See |string-match|.
|
Backslashes must be escaped e.g. "^\\.git". See |string-match|.
|
||||||
@@ -1188,6 +1203,8 @@ exists.
|
|||||||
- collapse_all `(keep_buffers?: bool)`
|
- collapse_all `(keep_buffers?: bool)`
|
||||||
- expand_all
|
- expand_all
|
||||||
- toggle_gitignore_filter
|
- toggle_gitignore_filter
|
||||||
|
- toggle_git_clean_filter
|
||||||
|
- toggle_no_buffer_filter
|
||||||
- toggle_custom_filter
|
- toggle_custom_filter
|
||||||
- toggle_hidden_filter
|
- toggle_hidden_filter
|
||||||
- toggle_help
|
- toggle_help
|
||||||
@@ -1302,55 +1319,57 @@ Single right / middle mouse mappings will requre changes to |mousemodel| or |mou
|
|||||||
|
|
||||||
DEFAULT MAPPINGS *nvim-tree-default-mappings*
|
DEFAULT MAPPINGS *nvim-tree-default-mappings*
|
||||||
|
|
||||||
`<CR>` edit open a file or folder; root will cd to the above directory
|
`<CR>` edit open a file or folder; root will cd to the above directory
|
||||||
`o`
|
`o`
|
||||||
`<2-LeftMouse>`
|
`<2-LeftMouse>`
|
||||||
`<C-e>` edit_in_place edit the file in place, effectively replacing the tree explorer
|
`<C-e>` edit_in_place edit the file in place, effectively replacing the tree explorer
|
||||||
`O` edit_no_picker same as (edit) with no window picker
|
`O` edit_no_picker same as (edit) with no window picker
|
||||||
`<C-]>` cd cd in the directory under the cursor
|
`<C-]>` cd cd in the directory under the cursor
|
||||||
`<2-RightMouse>`
|
`<2-RightMouse>`
|
||||||
`<C-v>` vsplit open the file in a vertical split
|
`<C-v>` vsplit open the file in a vertical split
|
||||||
`<C-x>` split open the file in a horizontal split
|
`<C-x>` split open the file in a horizontal split
|
||||||
`<C-t>` tabnew open the file in a new tab
|
`<C-t>` tabnew open the file in a new tab
|
||||||
`<` prev_sibling navigate to the previous sibling of current file/directory
|
`<` prev_sibling navigate to the previous sibling of current file/directory
|
||||||
`>` next_sibling navigate to the next sibling of current file/directory
|
`>` next_sibling navigate to the next sibling of current file/directory
|
||||||
`P` parent_node move cursor to the parent directory
|
`P` parent_node move cursor to the parent directory
|
||||||
`<BS>` close_node close current opened directory or parent
|
`<BS>` close_node close current opened directory or parent
|
||||||
`<Tab>` preview open the file as a preview (keeps the cursor in the tree)
|
`<Tab>` preview open the file as a preview (keeps the cursor in the tree)
|
||||||
`K` first_sibling navigate to the first sibling of current file/directory
|
`K` first_sibling navigate to the first sibling of current file/directory
|
||||||
`J` last_sibling navigate to the last sibling of current file/directory
|
`J` last_sibling navigate to the last sibling of current file/directory
|
||||||
`I` toggle_git_ignored toggle visibility of files/folders hidden via |git.ignore| option
|
`C` toggle_git_clean toggle visibility of git clean via |filters.git_clean| option
|
||||||
`H` toggle_dotfiles toggle visibility of dotfiles via |filters.dotfiles| option
|
`I` toggle_git_ignored toggle visibility of files/folders hidden via |git.ignore| option
|
||||||
`U` toggle_custom toggle visibility of files/folders hidden via |filters.custom| option
|
`H` toggle_dotfiles toggle visibility of dotfiles via |filters.dotfiles| option
|
||||||
`R` refresh refresh the tree
|
`B` toggle_no_buffer toggle visibility of files/folders hidden via |filters.no_buffer| option
|
||||||
`a` create add a file; leaving a trailing `/` will add a directory
|
`U` toggle_custom toggle visibility of files/folders hidden via |filters.custom| option
|
||||||
`d` remove delete a file (will prompt for confirmation)
|
`R` refresh refresh the tree
|
||||||
`D` trash trash a file via |trash| option
|
`a` create add a file; leaving a trailing `/` will add a directory
|
||||||
`r` rename rename a file
|
`d` remove delete a file (will prompt for confirmation)
|
||||||
`<C-r>` full_rename rename a file and omit the filename on input
|
`D` trash trash a file via |trash| option
|
||||||
`x` cut add/remove file/directory to cut clipboard
|
`r` rename rename a file
|
||||||
`c` copy add/remove file/directory to copy clipboard
|
`<C-r>` full_rename rename a file and omit the filename on input
|
||||||
`p` paste paste from clipboard; cut clipboard has precedence over copy; will prompt for confirmation
|
`x` cut add/remove file/directory to cut clipboard
|
||||||
`y` copy_name copy name to system clipboard
|
`c` copy add/remove file/directory to copy clipboard
|
||||||
`Y` copy_path copy relative path to system clipboard
|
`p` paste paste from clipboard; cut clipboard has precedence over copy; will prompt for confirmation
|
||||||
`gy` copy_absolute_path copy absolute path to system clipboard
|
`y` copy_name copy name to system clipboard
|
||||||
`[e` prev_diag_item go to next diagnostic item
|
`Y` copy_path copy relative path to system clipboard
|
||||||
`[c` prev_git_item go to next git item
|
`gy` copy_absolute_path copy absolute path to system clipboard
|
||||||
`]e` next_diag_item go to prev diagnostic item
|
`[e` prev_diag_item go to next diagnostic item
|
||||||
`]c` next_git_item go to prev git item
|
`[c` prev_git_item go to next git item
|
||||||
`-` dir_up navigate up to the parent directory of the current file/directory
|
`]e` next_diag_item go to prev diagnostic item
|
||||||
`s` system_open open a file with default system application or a folder with default file manager, using |system_open| option
|
`]c` next_git_item go to prev git item
|
||||||
`f` live_filter live filter nodes dynamically based on regex matching.
|
`-` dir_up navigate up to the parent directory of the current file/directory
|
||||||
`F` clear_live_filter clear live filter
|
`s` system_open open a file with default system application or a folder with default file manager, using |system_open| option
|
||||||
`q` close close tree window
|
`f` live_filter live filter nodes dynamically based on regex matching.
|
||||||
`W` collapse_all collapse the whole tree
|
`F` clear_live_filter clear live filter
|
||||||
`E` expand_all expand the whole tree, stopping after expanding |actions.expand_all.max_folder_discovery| folders; this might hang neovim for a while if running on a big folder
|
`q` close close tree window
|
||||||
`S` search_node prompt the user to enter a path and then expands the tree to match the path
|
`W` collapse_all collapse the whole tree
|
||||||
`.` run_file_command enter vim command mode with the file the cursor is on
|
`E` expand_all expand the whole tree, stopping after expanding |actions.expand_all.max_folder_discovery| folders; this might hang neovim for a while if running on a big folder
|
||||||
`<C-k>` toggle_file_info toggle a popup with file infos about the file under the cursor
|
`S` search_node prompt the user to enter a path and then expands the tree to match the path
|
||||||
`g?` toggle_help toggle help
|
`.` run_file_command enter vim command mode with the file the cursor is on
|
||||||
`m` toggle_mark Toggle node in bookmarks
|
`<C-k>` toggle_file_info toggle a popup with file infos about the file under the cursor
|
||||||
`bmv` bulk_move Move all bookmarked nodes into specified location
|
`g?` toggle_help toggle help
|
||||||
|
`m` toggle_mark Toggle node in bookmarks
|
||||||
|
`bmv` bulk_move Move all bookmarked nodes into specified location
|
||||||
|
|
||||||
>
|
>
|
||||||
view.mappings.list = { -- BEGIN_DEFAULT_MAPPINGS
|
view.mappings.list = { -- BEGIN_DEFAULT_MAPPINGS
|
||||||
@@ -1368,8 +1387,10 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
|
|||||||
{ key = "<Tab>", action = "preview" },
|
{ key = "<Tab>", action = "preview" },
|
||||||
{ key = "K", action = "first_sibling" },
|
{ key = "K", action = "first_sibling" },
|
||||||
{ key = "J", action = "last_sibling" },
|
{ key = "J", action = "last_sibling" },
|
||||||
|
{ key = "C", action = "toggle_git_clean" },
|
||||||
{ key = "I", action = "toggle_git_ignored" },
|
{ key = "I", action = "toggle_git_ignored" },
|
||||||
{ key = "H", action = "toggle_dotfiles" },
|
{ key = "H", action = "toggle_dotfiles" },
|
||||||
|
{ key = "B", action = "toggle_no_buffer" },
|
||||||
{ key = "U", action = "toggle_custom" },
|
{ key = "U", action = "toggle_custom" },
|
||||||
{ key = "R", action = "refresh" },
|
{ key = "R", action = "refresh" },
|
||||||
{ key = "a", action = "create" },
|
{ key = "a", action = "create" },
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ local reloaders = require "nvim-tree.actions.reloaders.reloaders"
|
|||||||
local copy_paste = require "nvim-tree.actions.fs.copy-paste"
|
local copy_paste = require "nvim-tree.actions.fs.copy-paste"
|
||||||
local collapse_all = require "nvim-tree.actions.tree-modifiers.collapse-all"
|
local collapse_all = require "nvim-tree.actions.tree-modifiers.collapse-all"
|
||||||
local git = require "nvim-tree.git"
|
local git = require "nvim-tree.git"
|
||||||
|
local filters = require "nvim-tree.explorer.filters"
|
||||||
|
|
||||||
local _config = {}
|
local _config = {}
|
||||||
|
|
||||||
@@ -353,6 +354,22 @@ local function setup_autocommands(opts)
|
|||||||
create_nvim_tree_autocmd("BufWritePost", { callback = reloaders.reload_explorer })
|
create_nvim_tree_autocmd("BufWritePost", { callback = reloaders.reload_explorer })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_nvim_tree_autocmd("BufReadPost", {
|
||||||
|
callback = function()
|
||||||
|
if filters.config.filter_no_buffer then
|
||||||
|
reloaders.reload_explorer()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
create_nvim_tree_autocmd("BufUnload", {
|
||||||
|
callback = function(data)
|
||||||
|
if filters.config.filter_no_buffer then
|
||||||
|
reloaders.reload_explorer(nil, data.buf)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
if not has_watchers and opts.git.enable then
|
if not has_watchers and opts.git.enable then
|
||||||
create_nvim_tree_autocmd("User", {
|
create_nvim_tree_autocmd("User", {
|
||||||
pattern = { "FugitiveChanged", "NeogitStatusRefreshed" },
|
pattern = { "FugitiveChanged", "NeogitStatusRefreshed" },
|
||||||
@@ -583,6 +600,8 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
|
|||||||
},
|
},
|
||||||
filters = {
|
filters = {
|
||||||
dotfiles = false,
|
dotfiles = false,
|
||||||
|
git_clean = false,
|
||||||
|
no_buffer = false,
|
||||||
custom = {},
|
custom = {},
|
||||||
exclude = {},
|
exclude = {},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ local Actions = {
|
|||||||
toggle_dotfiles = require("nvim-tree.actions.tree-modifiers.toggles").dotfiles,
|
toggle_dotfiles = require("nvim-tree.actions.tree-modifiers.toggles").dotfiles,
|
||||||
toggle_custom = require("nvim-tree.actions.tree-modifiers.toggles").custom,
|
toggle_custom = require("nvim-tree.actions.tree-modifiers.toggles").custom,
|
||||||
toggle_git_ignored = require("nvim-tree.actions.tree-modifiers.toggles").git_ignored,
|
toggle_git_ignored = require("nvim-tree.actions.tree-modifiers.toggles").git_ignored,
|
||||||
|
toggle_git_clean = require("nvim-tree.actions.tree-modifiers.toggles").git_clean,
|
||||||
|
toggle_no_buffer = require("nvim-tree.actions.tree-modifiers.toggles").no_buffer,
|
||||||
|
|
||||||
-- Filesystem operations
|
-- Filesystem operations
|
||||||
copy_absolute_path = require("nvim-tree.actions.fs.copy-paste").copy_absolute_path,
|
copy_absolute_path = require("nvim-tree.actions.fs.copy-paste").copy_absolute_path,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ local function search(search_dir, input_path)
|
|||||||
local function iter(dir)
|
local function iter(dir)
|
||||||
local realpath, path, name, stat, handle, _
|
local realpath, path, name, stat, handle, _
|
||||||
|
|
||||||
|
local filter_status = filters.prepare()
|
||||||
|
|
||||||
handle, _ = vim.loop.fs_scandir(dir)
|
handle, _ = vim.loop.fs_scandir(dir)
|
||||||
if not handle then
|
if not handle then
|
||||||
return
|
return
|
||||||
@@ -34,7 +36,7 @@ local function search(search_dir, input_path)
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
if not filters.should_ignore(path) then
|
if not filters.should_filter(path, filter_status) then
|
||||||
if string.find(path, "/" .. input_path .. "$") then
|
if string.find(path, "/" .. input_path .. "$") then
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ local DEFAULT_MAPPINGS = {
|
|||||||
action = "last_sibling",
|
action = "last_sibling",
|
||||||
desc = "navigate to the last sibling of current file/directory",
|
desc = "navigate to the last sibling of current file/directory",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key = "C",
|
||||||
|
action = "toggle_git_clean",
|
||||||
|
desc = "toggle visibility of git clean via |filters.git_clean| option",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key = "I",
|
key = "I",
|
||||||
action = "toggle_git_ignored",
|
action = "toggle_git_ignored",
|
||||||
@@ -86,6 +91,11 @@ local DEFAULT_MAPPINGS = {
|
|||||||
action = "toggle_dotfiles",
|
action = "toggle_dotfiles",
|
||||||
desc = "toggle visibility of dotfiles via |filters.dotfiles| option",
|
desc = "toggle visibility of dotfiles via |filters.dotfiles| option",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key = "B",
|
||||||
|
action = "toggle_no_buffer",
|
||||||
|
desc = "toggle visibility of files/folders hidden via |filters.no_buffer| option",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key = "U",
|
key = "U",
|
||||||
action = "toggle_custom",
|
action = "toggle_custom",
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ local core = require "nvim-tree.core"
|
|||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local function refresh_nodes(node, projects)
|
local function refresh_nodes(node, projects, unloaded_bufnr)
|
||||||
local cwd = node.cwd or node.link_to or node.absolute_path
|
local cwd = node.cwd or node.link_to or node.absolute_path
|
||||||
local project_root = git.get_project_root(cwd)
|
local project_root = git.get_project_root(cwd)
|
||||||
explorer_module.reload(node, projects[project_root] or {})
|
explorer_module.reload(node, projects[project_root] or {}, unloaded_bufnr)
|
||||||
for _, _node in ipairs(node.nodes) do
|
for _, _node in ipairs(node.nodes) do
|
||||||
if _node.nodes and _node.open then
|
if _node.nodes and _node.open then
|
||||||
refresh_nodes(_node, projects)
|
refresh_nodes(_node, projects, unloaded_bufnr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -33,14 +33,16 @@ function M.reload_node_status(parent_node, projects)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local event_running = false
|
local event_running = false
|
||||||
function M.reload_explorer()
|
---@param _ table unused node passed by action
|
||||||
|
---@param unloaded_bufnr number optional bufnr recently unloaded via BufUnload event
|
||||||
|
function M.reload_explorer(_, unloaded_bufnr)
|
||||||
if event_running or not core.get_explorer() or vim.v.exiting ~= vim.NIL then
|
if event_running or not core.get_explorer() or vim.v.exiting ~= vim.NIL then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
event_running = true
|
event_running = true
|
||||||
|
|
||||||
local projects = git.reload()
|
local projects = git.reload()
|
||||||
refresh_nodes(core.get_explorer(), projects)
|
refresh_nodes(core.get_explorer(), projects, unloaded_bufnr)
|
||||||
if view.is_visible() then
|
if view.is_visible() then
|
||||||
renderer.draw()
|
renderer.draw()
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,6 +15,16 @@ function M.git_ignored()
|
|||||||
return reloaders.reload_explorer()
|
return reloaders.reload_explorer()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.git_clean()
|
||||||
|
filters.config.filter_git_clean = not filters.config.filter_git_clean
|
||||||
|
return reloaders.reload_explorer()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.no_buffer()
|
||||||
|
filters.config.filter_no_buffer = not filters.config.filter_no_buffer
|
||||||
|
return reloaders.reload_explorer()
|
||||||
|
end
|
||||||
|
|
||||||
function M.dotfiles()
|
function M.dotfiles()
|
||||||
filters.config.filter_dotfiles = not filters.config.filter_dotfiles
|
filters.config.filter_dotfiles = not filters.config.filter_dotfiles
|
||||||
return reloaders.reload_explorer()
|
return reloaders.reload_explorer()
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ Api.tree.search_node = require("nvim-tree.actions.finders.search-node").fn
|
|||||||
Api.tree.collapse_all = require("nvim-tree.actions.tree-modifiers.collapse-all").fn
|
Api.tree.collapse_all = require("nvim-tree.actions.tree-modifiers.collapse-all").fn
|
||||||
Api.tree.expand_all = inject_node(require("nvim-tree.actions.tree-modifiers.expand-all").fn)
|
Api.tree.expand_all = inject_node(require("nvim-tree.actions.tree-modifiers.expand-all").fn)
|
||||||
Api.tree.toggle_gitignore_filter = require("nvim-tree.actions.tree-modifiers.toggles").git_ignored
|
Api.tree.toggle_gitignore_filter = require("nvim-tree.actions.tree-modifiers.toggles").git_ignored
|
||||||
|
Api.tree.toggle_git_clean_filter = require("nvim-tree.actions.tree-modifiers.toggles").git_clean
|
||||||
|
Api.tree.toggle_no_buffer_filter = require("nvim-tree.actions.tree-modifiers.toggles").no_buffer
|
||||||
Api.tree.toggle_custom_filter = require("nvim-tree.actions.tree-modifiers.toggles").custom
|
Api.tree.toggle_custom_filter = require("nvim-tree.actions.tree-modifiers.toggles").custom
|
||||||
Api.tree.toggle_hidden_filter = require("nvim-tree.actions.tree-modifiers.toggles").dotfiles
|
Api.tree.toggle_hidden_filter = require("nvim-tree.actions.tree-modifiers.toggles").dotfiles
|
||||||
Api.tree.toggle_help = require("nvim-tree.actions.tree-modifiers.toggles").help
|
Api.tree.toggle_help = require("nvim-tree.actions.tree-modifiers.toggles").help
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ local function get_type_from(type_, cwd)
|
|||||||
return type_ or (vim.loop.fs_stat(cwd) or {}).type
|
return type_ or (vim.loop.fs_stat(cwd) or {}).type
|
||||||
end
|
end
|
||||||
|
|
||||||
local function populate_children(handle, cwd, node, status)
|
local function populate_children(handle, cwd, node, git_status)
|
||||||
local node_ignored = node.git_status == "!!"
|
local node_ignored = node.git_status == "!!"
|
||||||
local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
|
local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
|
||||||
|
local filter_status = filters.prepare(git_status)
|
||||||
while true do
|
while true do
|
||||||
local name, t = vim.loop.fs_scandir_next(handle)
|
local name, t = vim.loop.fs_scandir_next(handle)
|
||||||
if not name then
|
if not name then
|
||||||
@@ -23,11 +24,7 @@ local function populate_children(handle, cwd, node, status)
|
|||||||
|
|
||||||
local abs = utils.path_join { cwd, name }
|
local abs = utils.path_join { cwd, name }
|
||||||
t = get_type_from(t, abs)
|
t = get_type_from(t, abs)
|
||||||
if
|
if not filters.should_filter(abs, filter_status) and not nodes_by_path[abs] then
|
||||||
not filters.should_ignore(abs)
|
|
||||||
and not filters.should_ignore_git(abs, status.files)
|
|
||||||
and not nodes_by_path[abs]
|
|
||||||
then
|
|
||||||
local child = nil
|
local child = nil
|
||||||
if t == "directory" and vim.loop.fs_access(abs, "R") then
|
if t == "directory" and vim.loop.fs_access(abs, "R") then
|
||||||
child = builders.folder(node, abs, name)
|
child = builders.folder(node, abs, name)
|
||||||
@@ -42,7 +39,7 @@ local function populate_children(handle, cwd, node, status)
|
|||||||
if child then
|
if child then
|
||||||
table.insert(node.nodes, child)
|
table.insert(node.nodes, child)
|
||||||
nodes_by_path[child.absolute_path] = true
|
nodes_by_path[child.absolute_path] = true
|
||||||
common.update_git_status(child, node_ignored, status)
|
common.update_git_status(child, node_ignored, git_status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,26 +14,63 @@ local function is_excluded(path)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
---Check if the given path should be ignored.
|
---Check if the given path is git clean/ignored
|
||||||
---@param path string Absolute path
|
---@param path string Absolute path
|
||||||
|
---@param git_status table from prepare
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function M.should_ignore(path)
|
local function git(path, git_status)
|
||||||
local basename = utils.path_basename(path)
|
if type(git_status) ~= "table" or type(git_status.files) ~= "table" or type(git_status.dirs) ~= "table" then
|
||||||
|
|
||||||
if is_excluded(path) then
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if M.config.filter_dotfiles then
|
-- default status to clean
|
||||||
if basename:sub(1, 1) == "." then
|
local status = git_status.files[path] or git_status.dirs[path] or " "
|
||||||
return true
|
|
||||||
|
-- filter ignored; overrides clean as they are effectively dirty
|
||||||
|
if M.config.filter_git_ignored and status == "!!" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- filter clean
|
||||||
|
if M.config.filter_git_clean and status == " " then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
---Check if the given path has no listed buffer
|
||||||
|
---@param path string Absolute path
|
||||||
|
---@param bufinfo table vim.fn.getbufinfo { buflisted = 1 }
|
||||||
|
---@param unloaded_bufnr number optional bufnr recently unloaded via BufUnload event
|
||||||
|
---@return boolean
|
||||||
|
local function buf(path, bufinfo, unloaded_bufnr)
|
||||||
|
if not M.config.filter_no_buffer or type(bufinfo) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- filter files with no open buffer and directories containing no open buffers
|
||||||
|
for _, b in ipairs(bufinfo) do
|
||||||
|
if b.name == path or b.name:find(path .. "/", 1, true) and b.bufnr ~= unloaded_bufnr then
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dotfile(path)
|
||||||
|
return M.config.filter_dotfiles and utils.path_basename(path):sub(1, 1) == "."
|
||||||
|
end
|
||||||
|
|
||||||
|
local function custom(path)
|
||||||
if not M.config.filter_custom then
|
if not M.config.filter_custom then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local basename = utils.path_basename(path)
|
||||||
|
|
||||||
|
-- filter custom regexes
|
||||||
local relpath = utils.path_relative(path, vim.loop.cwd())
|
local relpath = utils.path_relative(path, vim.loop.cwd())
|
||||||
for pat, _ in pairs(M.ignore_list) do
|
for pat, _ in pairs(M.ignore_list) do
|
||||||
if vim.fn.match(relpath, pat) ~= -1 or vim.fn.match(basename, pat) ~= -1 then
|
if vim.fn.match(relpath, pat) ~= -1 or vim.fn.match(basename, pat) ~= -1 then
|
||||||
@@ -51,10 +88,41 @@ function M.should_ignore(path)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.should_ignore_git(path, status)
|
---Prepare arguments for should_filter. This is done prior to should_filter for efficiency reasons.
|
||||||
return M.config.filter_git_ignored
|
---@param git_status table results of git.load_project_status(...)
|
||||||
and (M.config.filter_git_ignored and status and status[path] == "!!")
|
---@param unloaded_bufnr number optional bufnr recently unloaded via BufUnload event
|
||||||
and not is_excluded(path)
|
---@return table
|
||||||
|
--- git_status: reference
|
||||||
|
--- unloaded_bufnr: copy
|
||||||
|
--- bufinfo: empty unless no_buffer set: vim.fn.getbufinfo { buflisted = 1 }
|
||||||
|
function M.prepare(git_status, unloaded_bufnr)
|
||||||
|
local status = {
|
||||||
|
git_status = git_status or {},
|
||||||
|
unloaded_bufnr = unloaded_bufnr,
|
||||||
|
bufinfo = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if M.config.filter_no_buffer then
|
||||||
|
status.bufinfo = vim.fn.getbufinfo { buflisted = 1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
return status
|
||||||
|
end
|
||||||
|
|
||||||
|
---Check if the given path should be filtered.
|
||||||
|
---@param path string Absolute path
|
||||||
|
---@param status table from prepare
|
||||||
|
---@return boolean
|
||||||
|
function M.should_filter(path, status)
|
||||||
|
-- exclusions override all filters
|
||||||
|
if is_excluded(path) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return git(path, status.git_status)
|
||||||
|
or buf(path, status.bufinfo, status.unloaded_bufnr)
|
||||||
|
or dotfile(path)
|
||||||
|
or custom(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
@@ -62,6 +130,8 @@ function M.setup(opts)
|
|||||||
filter_custom = true,
|
filter_custom = true,
|
||||||
filter_dotfiles = opts.filters.dotfiles,
|
filter_dotfiles = opts.filters.dotfiles,
|
||||||
filter_git_ignored = opts.git.ignore,
|
filter_git_ignored = opts.git.ignore,
|
||||||
|
filter_git_clean = opts.filters.git_clean,
|
||||||
|
filter_no_buffer = opts.filters.no_buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
M.ignore_list = {}
|
M.ignore_list = {}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ local function update_parent_statuses(node, project, root)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.reload(node, status)
|
function M.reload(node, git_status, unloaded_bufnr)
|
||||||
local cwd = node.link_to or node.absolute_path
|
local cwd = node.link_to or node.absolute_path
|
||||||
local handle = vim.loop.fs_scandir(cwd)
|
local handle = vim.loop.fs_scandir(cwd)
|
||||||
if type(handle) == "string" then
|
if type(handle) == "string" then
|
||||||
@@ -44,6 +44,8 @@ function M.reload(node, status)
|
|||||||
|
|
||||||
local ps = log.profile_start("reload %s", node.absolute_path)
|
local ps = log.profile_start("reload %s", node.absolute_path)
|
||||||
|
|
||||||
|
local filter_status = filters.prepare(git_status, unloaded_bufnr)
|
||||||
|
|
||||||
if node.group_next then
|
if node.group_next then
|
||||||
node.nodes = { node.group_next }
|
node.nodes = { node.group_next }
|
||||||
node.group_next = nil
|
node.group_next = nil
|
||||||
@@ -71,7 +73,7 @@ function M.reload(node, status)
|
|||||||
|
|
||||||
local abs = utils.path_join { cwd, name }
|
local abs = utils.path_join { cwd, name }
|
||||||
t = t or (fs_stat_cached(abs) or {}).type
|
t = t or (fs_stat_cached(abs) or {}).type
|
||||||
if not filters.should_ignore(abs) and not filters.should_ignore_git(abs, status.files) then
|
if not filters.should_filter(abs, filter_status) then
|
||||||
child_names[abs] = true
|
child_names[abs] = true
|
||||||
|
|
||||||
-- Recreate node if type changes.
|
-- Recreate node if type changes.
|
||||||
@@ -112,7 +114,7 @@ function M.reload(node, status)
|
|||||||
end
|
end
|
||||||
|
|
||||||
node.nodes = vim.tbl_map(
|
node.nodes = vim.tbl_map(
|
||||||
update_status(nodes_by_path, node_ignored, status),
|
update_status(nodes_by_path, node_ignored, git_status),
|
||||||
vim.tbl_filter(function(n)
|
vim.tbl_filter(function(n)
|
||||||
if child_names[n.absolute_path] then
|
if child_names[n.absolute_path] then
|
||||||
return child_names[n.absolute_path]
|
return child_names[n.absolute_path]
|
||||||
@@ -127,7 +129,7 @@ function M.reload(node, status)
|
|||||||
local child_folder_only = common.has_one_child_folder(node) and node.nodes[1]
|
local child_folder_only = common.has_one_child_folder(node) and node.nodes[1]
|
||||||
if M.config.group_empty and not is_root and child_folder_only then
|
if M.config.group_empty and not is_root and child_folder_only then
|
||||||
node.group_next = child_folder_only
|
node.group_next = child_folder_only
|
||||||
local ns = M.reload(child_folder_only, status)
|
local ns = M.reload(child_folder_only, git_status)
|
||||||
node.nodes = ns or {}
|
node.nodes = ns or {}
|
||||||
log.profile_end(ps, "reload %s", node.absolute_path)
|
log.profile_end(ps, "reload %s", node.absolute_path)
|
||||||
return ns
|
return ns
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ end
|
|||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
M.config = opts.renderer.icons
|
M.config = opts.renderer.icons
|
||||||
|
|
||||||
M.devicons = pcall(require, "nvim-web-devicons") and require "nvim-web-devicons"
|
M.devicons = pcall(require, "nvim-web-devicons") and require "nvim-web-devicons" or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
Reference in New Issue
Block a user