refacto: move filters and sorters in their own modules

Also exclude filters is taken into account in git ignore
fixes #892
This commit is contained in:
kiyan 2022-03-06 14:14:56 +01:00
parent 5cfe768882
commit 76d181d480
8 changed files with 159 additions and 136 deletions

View File

@ -1,17 +1,17 @@
local view = require"nvim-tree.view"
local eutils = require"nvim-tree.explorer.utils"
local filters = require"nvim-tree.explorer.filters"
local renderer = require"nvim-tree.renderer"
local reloaders = require"nvim-tree.actions.reloaders"
local M = {}
function M.ignored()
eutils.config.filter_ignored = not eutils.config.filter_ignored
filters.config.filter_ignored = not filters.config.filter_ignored
return reloaders.reload_explorer()
end
function M.dotfiles()
eutils.config.filter_dotfiles = not eutils.config.filter_dotfiles
filters.config.filter_dotfiles = not filters.config.filter_dotfiles
return reloaders.reload_explorer()
end

View File

@ -0,0 +1,11 @@
local uv = vim.loop
local M = {}
function M.has_one_child_folder(node)
return #node.nodes == 1
and node.nodes[1].nodes
and uv.fs_access(node.nodes[1].absolute_path, 'R')
end
return M

View File

@ -2,8 +2,10 @@ local api = vim.api
local uv = vim.loop
local utils = require'nvim-tree.utils'
local eutils = require'nvim-tree.explorer.utils'
local builders = require'nvim-tree.explorer.node-builders'
local common = require'nvim-tree.explorer.common'
local sorters = require"nvim-tree.explorer.sorters"
local filters = require"nvim-tree.explorer.filters"
local M = {}
@ -19,7 +21,7 @@ local function populate_children(handle, cwd, node, status)
local abs = utils.path_join({cwd, name})
t = get_type_from(t, abs)
if not eutils.should_ignore(abs) and not eutils.should_ignore_git(abs, status.files) then
if not filters.should_ignore(abs) and not filters.should_ignore_git(abs, status.files) then
if t == 'directory' and uv.fs_access(abs, 'R') then
table.insert(node.nodes, builders.folder(abs, name, status, node_ignored))
elseif t == 'file' then
@ -51,7 +53,7 @@ function M.explore(node, status)
populate_children(handle, cwd, node, status)
local is_root = node.cwd ~= nil
local child_folder_only = eutils.has_one_child_folder(node) and node.nodes[1]
local child_folder_only = common.has_one_child_folder(node) and node.nodes[1]
if vim.g.nvim_tree_group_empty == 1 and not is_root and child_folder_only then
node.group_next = child_folder_only
local ns = M.explore(child_folder_only, status)
@ -59,7 +61,7 @@ function M.explore(node, status)
return ns
end
utils.merge_sort(node.nodes, eutils.node_comparator)
sorters.merge_sort(node.nodes, sorters.node_comparator)
return node.nodes
end

View File

@ -1,48 +1,17 @@
local uv = vim.loop
local utils = require'nvim-tree.utils'
local M = {
ignore_list = {},
exclude_list = {},
node_comparator = nil,
}
function M.node_comparator_name(a, b)
if not (a and b) then
return true
local function is_excluded(path)
for _, node in ipairs(M.exclude_list) do
if path:match(node) then
return true
end
end
if a.nodes and not b.nodes then
return true
elseif not a.nodes and b.nodes then
return false
end
return a.name:lower() <= b.name:lower()
end
function M.node_comparator_modification_time(a, b)
if not (a and b) then
return true
end
if a.nodes and not b.nodes then
return true
elseif not a.nodes and b.nodes then
return false
end
local last_modified_a = 0
local last_modified_b = 0
if a.fs_stat ~= nil then
last_modified_a = a.fs_stat.mtime.sec
end
if b.fs_stat ~= nil then
last_modified_b = b.fs_stat.mtime.sec
end
return last_modified_a <= last_modified_b
return false
end
---Check if the given path should be ignored.
@ -51,10 +20,8 @@ end
function M.should_ignore(path)
local basename = utils.path_basename(path)
for _, node in ipairs(M.exclude_list) do
if path:match(node) then
return false
end
if is_excluded(path) then
return false
end
if M.config.filter_dotfiles then
@ -85,12 +52,7 @@ end
function M.should_ignore_git(path, status)
return M.config.filter_ignored
and (M.config.filter_git_ignored and status and status[path] == '!!')
end
function M.has_one_child_folder(node)
return #node.nodes == 1
and node.nodes[1].nodes
and uv.fs_access(node.nodes[1].absolute_path, 'R')
and not is_excluded(path)
end
function M.setup(opts)
@ -98,7 +60,6 @@ function M.setup(opts)
filter_ignored = true,
filter_dotfiles = opts.filters.dotfiles,
filter_git_ignored = opts.git.ignore,
sort_by = opts.sort_by,
}
M.exclude_list = opts.filters.exclude
@ -109,12 +70,6 @@ function M.setup(opts)
M.ignore_list[filter_name] = true
end
end
if M.config.sort_by == "modification_time" then
M.node_comparator = M.node_comparator_modification_time
else
M.node_comparator = M.node_comparator_name
end
end
return M

View File

@ -31,7 +31,8 @@ function Explorer:expand(node)
end
function M.setup(opts)
require"nvim-tree.explorer.utils".setup(opts)
require"nvim-tree.explorer.filters".setup(opts)
require"nvim-tree.explorer.sorters".setup(opts)
end
M.Explorer = Explorer

View File

@ -2,8 +2,10 @@ local api = vim.api
local uv = vim.loop
local utils = require'nvim-tree.utils'
local eutils = require'nvim-tree.explorer.utils'
local builders = require'nvim-tree.explorer.node-builders'
local common = require'nvim-tree.explorer.common'
local filters = require'nvim-tree.explorer.filters'
local sorters = require'nvim-tree.explorer.sorters'
local M = {}
@ -51,7 +53,7 @@ function M.reload(node, status)
local abs = utils.path_join({cwd, name})
t = t or (uv.fs_stat(abs) or {}).type
if not eutils.should_ignore(abs) and not eutils.should_ignore_git(abs, status.files) then
if not filters.should_ignore(abs) and not filters.should_ignore_git(abs, status.files) then
child_names[abs] = true
if not nodes_by_path[abs] then
if t == 'directory' and uv.fs_access(abs, 'R') then
@ -76,7 +78,7 @@ function M.reload(node, status)
))
local is_root = node.cwd ~= nil
local child_folder_only = eutils.has_one_child_folder(node) and node.nodes[1]
local child_folder_only = common.has_one_child_folder(node) and node.nodes[1]
if vim.g.nvim_tree_group_empty == 1 and not is_root and child_folder_only then
node.group_next = child_folder_only
local ns = M.reload(child_folder_only, status)
@ -84,7 +86,7 @@ function M.reload(node, status)
return ns
end
utils.merge_sort(node.nodes, eutils.node_comparator)
sorters.merge_sort(node.nodes, sorters.node_comparator)
return node.nodes
end

View File

@ -0,0 +1,122 @@
local M = {
sort_by = nil,
node_comparator = nil,
}
---Create a shallow copy of a portion of a list.
---@param t table
---@param first integer First index, inclusive
---@param last integer Last index, inclusive
---@return table
local function tbl_slice(t, first, last)
local slice = {}
for i = first, last or #t, 1 do
table.insert(slice, t[i])
end
return slice
end
local function merge(t, first, mid, last, comparator)
local n1 = mid - first + 1
local n2 = last - mid
local ls = tbl_slice(t, first, mid)
local rs = tbl_slice(t, mid + 1, last)
local i = 1
local j = 1
local k = first
while (i <= n1 and j <= n2) do
if comparator(ls[i], rs[j]) then
t[k] = ls[i]
i = i + 1
else
t[k] = rs[j]
j = j + 1
end
k = k + 1
end
while i <= n1 do
t[k] = ls[i]
i = i + 1
k = k + 1
end
while j <= n2 do
t[k] = rs[j]
j = j + 1
k = k + 1
end
end
local function split_merge(t, first, last, comparator)
if (last - first) < 1 then return end
local mid = math.floor((first + last) / 2)
split_merge(t, first, mid, comparator)
split_merge(t, mid + 1, last, comparator)
merge(t, first, mid, last, comparator)
end
---Perform a merge sort on a given list.
---@param t any[]
---@param comparator function|nil
function M.merge_sort(t, comparator)
if not comparator then
comparator = function (left, right)
return left < right
end
end
split_merge(t, 1, #t, comparator)
end
function M.node_comparator_name(a, b)
if not (a and b) then
return true
end
if a.nodes and not b.nodes then
return true
elseif not a.nodes and b.nodes then
return false
end
return a.name:lower() <= b.name:lower()
end
function M.node_comparator_modification_time(a, b)
if not (a and b) then
return true
end
if a.nodes and not b.nodes then
return true
elseif not a.nodes and b.nodes then
return false
end
local last_modified_a = 0
local last_modified_b = 0
if a.fs_stat ~= nil then
last_modified_a = a.fs_stat.mtime.sec
end
if b.fs_stat ~= nil then
last_modified_b = b.fs_stat.mtime.sec
end
return last_modified_a <= last_modified_b
end
function M.setup(opts)
M.sort_by = opts.sort_by
if M.sort_by == "modification_time" then
M.node_comparator = M.node_comparator_modification_time
else
M.node_comparator = M.node_comparator_name
end
end
return M

View File

@ -113,76 +113,6 @@ function M.find_node(_nodes, _fn)
return node, i
end
---Create a shallow copy of a portion of a list.
---@param t table
---@param first integer First index, inclusive
---@param last integer Last index, inclusive
---@return table
function M.tbl_slice(t, first, last)
local slice = {}
for i = first, last or #t, 1 do
table.insert(slice, t[i])
end
return slice
end
local function merge(t, first, mid, last, comparator)
local n1 = mid - first + 1
local n2 = last - mid
local ls = M.tbl_slice(t, first, mid)
local rs = M.tbl_slice(t, mid + 1, last)
local i = 1
local j = 1
local k = first
while (i <= n1 and j <= n2) do
if comparator(ls[i], rs[j]) then
t[k] = ls[i]
i = i + 1
else
t[k] = rs[j]
j = j + 1
end
k = k + 1
end
while i <= n1 do
t[k] = ls[i]
i = i + 1
k = k + 1
end
while j <= n2 do
t[k] = rs[j]
j = j + 1
k = k + 1
end
end
local function split_merge(t, first, last, comparator)
if (last - first) < 1 then return end
local mid = math.floor((first + last) / 2)
split_merge(t, first, mid, comparator)
split_merge(t, mid + 1, last, comparator)
merge(t, first, mid, last, comparator)
end
---Perform a merge sort on a given list.
---@param t any[]
---@param comparator function|nil
function M.merge_sort(t, comparator)
if not comparator then
comparator = function (left, right)
return left < right
end
end
split_merge(t, 1, #t, comparator)
end
---Matching executable files in Windows.
---@param ext string
---@return boolean