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:
parent
5cfe768882
commit
76d181d480
@ -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
|
||||
|
||||
|
||||
11
lua/nvim-tree/explorer/common.lua
Normal file
11
lua/nvim-tree/explorer/common.lua
Normal 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
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
122
lua/nvim-tree/explorer/sorters.lua
Normal file
122
lua/nvim-tree/explorer/sorters.lua
Normal 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
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user