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 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 renderer = require"nvim-tree.renderer"
|
||||||
local reloaders = require"nvim-tree.actions.reloaders"
|
local reloaders = require"nvim-tree.actions.reloaders"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
function M.ignored()
|
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()
|
return reloaders.reload_explorer()
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.dotfiles()
|
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()
|
return reloaders.reload_explorer()
|
||||||
end
|
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 uv = vim.loop
|
||||||
|
|
||||||
local utils = require'nvim-tree.utils'
|
local utils = require'nvim-tree.utils'
|
||||||
local eutils = require'nvim-tree.explorer.utils'
|
|
||||||
local builders = require'nvim-tree.explorer.node-builders'
|
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 = {}
|
local M = {}
|
||||||
|
|
||||||
@ -19,7 +21,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 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
|
if t == 'directory' and uv.fs_access(abs, 'R') then
|
||||||
table.insert(node.nodes, builders.folder(abs, name, status, node_ignored))
|
table.insert(node.nodes, builders.folder(abs, name, status, node_ignored))
|
||||||
elseif t == 'file' then
|
elseif t == 'file' then
|
||||||
@ -51,7 +53,7 @@ function M.explore(node, status)
|
|||||||
populate_children(handle, cwd, node, status)
|
populate_children(handle, cwd, node, status)
|
||||||
|
|
||||||
local is_root = node.cwd ~= nil
|
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
|
if vim.g.nvim_tree_group_empty == 1 and not is_root and child_folder_only then
|
||||||
node.group_next = child_folder_only
|
node.group_next = child_folder_only
|
||||||
local ns = M.explore(child_folder_only, status)
|
local ns = M.explore(child_folder_only, status)
|
||||||
@ -59,7 +61,7 @@ function M.explore(node, status)
|
|||||||
return ns
|
return ns
|
||||||
end
|
end
|
||||||
|
|
||||||
utils.merge_sort(node.nodes, eutils.node_comparator)
|
sorters.merge_sort(node.nodes, sorters.node_comparator)
|
||||||
return node.nodes
|
return node.nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,48 +1,17 @@
|
|||||||
local uv = vim.loop
|
|
||||||
|
|
||||||
local utils = require'nvim-tree.utils'
|
local utils = require'nvim-tree.utils'
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
ignore_list = {},
|
ignore_list = {},
|
||||||
exclude_list = {},
|
exclude_list = {},
|
||||||
node_comparator = nil,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function M.node_comparator_name(a, b)
|
local function is_excluded(path)
|
||||||
if not (a and b) then
|
for _, node in ipairs(M.exclude_list) do
|
||||||
return true
|
if path:match(node) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if a.nodes and not b.nodes then
|
return false
|
||||||
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
|
end
|
||||||
|
|
||||||
---Check if the given path should be ignored.
|
---Check if the given path should be ignored.
|
||||||
@ -51,10 +20,8 @@ end
|
|||||||
function M.should_ignore(path)
|
function M.should_ignore(path)
|
||||||
local basename = utils.path_basename(path)
|
local basename = utils.path_basename(path)
|
||||||
|
|
||||||
for _, node in ipairs(M.exclude_list) do
|
if is_excluded(path) then
|
||||||
if path:match(node) then
|
return false
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if M.config.filter_dotfiles then
|
if M.config.filter_dotfiles then
|
||||||
@ -85,12 +52,7 @@ end
|
|||||||
function M.should_ignore_git(path, status)
|
function M.should_ignore_git(path, status)
|
||||||
return M.config.filter_ignored
|
return M.config.filter_ignored
|
||||||
and (M.config.filter_git_ignored and status and status[path] == '!!')
|
and (M.config.filter_git_ignored and status and status[path] == '!!')
|
||||||
end
|
and not is_excluded(path)
|
||||||
|
|
||||||
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
|
end
|
||||||
|
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
@ -98,7 +60,6 @@ function M.setup(opts)
|
|||||||
filter_ignored = true,
|
filter_ignored = true,
|
||||||
filter_dotfiles = opts.filters.dotfiles,
|
filter_dotfiles = opts.filters.dotfiles,
|
||||||
filter_git_ignored = opts.git.ignore,
|
filter_git_ignored = opts.git.ignore,
|
||||||
sort_by = opts.sort_by,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
M.exclude_list = opts.filters.exclude
|
M.exclude_list = opts.filters.exclude
|
||||||
@ -109,12 +70,6 @@ function M.setup(opts)
|
|||||||
M.ignore_list[filter_name] = true
|
M.ignore_list[filter_name] = true
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
@ -31,7 +31,8 @@ function Explorer:expand(node)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.setup(opts)
|
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
|
end
|
||||||
|
|
||||||
M.Explorer = Explorer
|
M.Explorer = Explorer
|
||||||
|
|||||||
@ -2,8 +2,10 @@ local api = vim.api
|
|||||||
local uv = vim.loop
|
local uv = vim.loop
|
||||||
|
|
||||||
local utils = require'nvim-tree.utils'
|
local utils = require'nvim-tree.utils'
|
||||||
local eutils = require'nvim-tree.explorer.utils'
|
|
||||||
local builders = require'nvim-tree.explorer.node-builders'
|
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 = {}
|
local M = {}
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ function M.reload(node, status)
|
|||||||
|
|
||||||
local abs = utils.path_join({cwd, name})
|
local abs = utils.path_join({cwd, name})
|
||||||
t = t or (uv.fs_stat(abs) or {}).type
|
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
|
child_names[abs] = true
|
||||||
if not nodes_by_path[abs] then
|
if not nodes_by_path[abs] then
|
||||||
if t == 'directory' and uv.fs_access(abs, 'R') 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 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
|
if vim.g.nvim_tree_group_empty == 1 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, status)
|
||||||
@ -84,7 +86,7 @@ function M.reload(node, status)
|
|||||||
return ns
|
return ns
|
||||||
end
|
end
|
||||||
|
|
||||||
utils.merge_sort(node.nodes, eutils.node_comparator)
|
sorters.merge_sort(node.nodes, sorters.node_comparator)
|
||||||
return node.nodes
|
return node.nodes
|
||||||
end
|
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
|
return node, i
|
||||||
end
|
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.
|
---Matching executable files in Windows.
|
||||||
---@param ext string
|
---@param ext string
|
||||||
---@return boolean
|
---@return boolean
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user