chore: resolve undefined-field warnings, fix link git statuses, rewrite devicons (#2968)
* add todo * refactor(#2886): multi instance: node class refactoring: extract links, *_git_status (#2944) * extract DirectoryLinkNode and FileLinkNode, move Node methods to children * temporarily move DirectoryNode methods into BaseNode for easier reviewing * move mostly unchanged DirectoryNode methods back to BaseNode * tidy * git.git_status_file takes an array * update git status of links * luacheck hack * safer git_status_dir * refactor(#2886): multi instance: node class refactoring: DirectoryNode:expand_or_collapse (#2957) move expand_or_collapse to DirectoryNode * refactor(#2886): multi instance: node group functions refactoring (#2959) * move last_group_node to DirectoryNode * move add BaseNode:as and more doc * revert parameter name changes * revert parameter name changes * add Class * move group methods into DN * tidy group methods * tidy group methods * tidy group methods * tidy group methods * parent is DirectoryNode * tidy expand all * BaseNode -> Node * move watcher to DirectoryNode * last_group_node is DirectoryNode only * simplify create-file * simplify parent * simplify collapse-all * simplify live-filter * style * move lib.get_cursor_position to Explorer * move lib.get_node_at_cursor to Explorer * move lib.get_nodes to Explorer * move place_cursor_on_node to Explorer * resolve resource leak in purge_all_state * move many autocommands into Explorer * post merge tidy * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * Revert "chore: resolve undefined-field" This reverts commit be546ff18d41f28466b065c857e1e041659bd2c8. * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * Revert "chore: resolve undefined-field" This reverts commite82db1c44d. * chore: resolve undefined-field * chore: class new is now generic * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * Revert "chore: resolve undefined-field" This reverts commit0e9b844d22. * move icon builders into node classes * move icon builders into node classes * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * chore: resolve undefined-field * move folder specifics from icons to Directory * move folder specifics from icons to Directory * move folder specifics from icons to Directory * move folder specifics from icons to Directory * move file specifics from icons to File * clean up sorters * chore: resolve undefined-field * tidy hl icon name * file devicon uses library to fall back * file devicon uses library to fall back * file devicon uses library to fall back
This commit is contained in:
committed by
GitHub
parent
c22124b374
commit
610a1c189b
@@ -57,25 +57,25 @@ end
|
||||
|
||||
---Check if the given path is git clean/ignored
|
||||
---@param path string Absolute path
|
||||
---@param git_status table from prepare
|
||||
---@param project GitProject from prepare
|
||||
---@return boolean
|
||||
local function git(self, path, git_status)
|
||||
if type(git_status) ~= "table" or type(git_status.files) ~= "table" or type(git_status.dirs) ~= "table" then
|
||||
local function git(self, path, project)
|
||||
if type(project) ~= "table" or type(project.files) ~= "table" or type(project.dirs) ~= "table" then
|
||||
return false
|
||||
end
|
||||
|
||||
-- default status to clean
|
||||
local status = git_status.files[path]
|
||||
status = status or git_status.dirs.direct[path] and git_status.dirs.direct[path][1]
|
||||
status = status or git_status.dirs.indirect[path] and git_status.dirs.indirect[path][1]
|
||||
local xy = project.files[path]
|
||||
xy = xy or project.dirs.direct[path] and project.dirs.direct[path][1]
|
||||
xy = xy or project.dirs.indirect[path] and project.dirs.indirect[path][1]
|
||||
|
||||
-- filter ignored; overrides clean as they are effectively dirty
|
||||
if self.config.filter_git_ignored and status == "!!" then
|
||||
if self.config.filter_git_ignored and xy == "!!" then
|
||||
return true
|
||||
end
|
||||
|
||||
-- filter clean
|
||||
if self.config.filter_git_clean and not status then
|
||||
if self.config.filter_git_clean and not xy then
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -178,14 +178,14 @@ local function custom(self, path)
|
||||
end
|
||||
|
||||
---Prepare arguments for should_filter. This is done prior to should_filter for efficiency reasons.
|
||||
---@param git_status table|nil optional results of git.load_project_status(...)
|
||||
---@param project GitProject? optional results of git.load_projects(...)
|
||||
---@return table
|
||||
--- git_status: reference
|
||||
--- project: reference
|
||||
--- bufinfo: empty unless no_buffer set: vim.fn.getbufinfo { buflisted = 1 }
|
||||
--- bookmarks: absolute paths to boolean
|
||||
function Filters:prepare(git_status)
|
||||
function Filters:prepare(project)
|
||||
local status = {
|
||||
git_status = git_status or {},
|
||||
project = project or {},
|
||||
bufinfo = {},
|
||||
bookmarks = {},
|
||||
}
|
||||
@@ -219,7 +219,7 @@ function Filters:should_filter(path, fs_stat, status)
|
||||
return false
|
||||
end
|
||||
|
||||
return git(self, path, status.git_status)
|
||||
return git(self, path, status.project)
|
||||
or buf(self, path, status.bufinfo)
|
||||
or dotfile(self, path)
|
||||
or custom(self, path)
|
||||
@@ -240,7 +240,7 @@ function Filters:should_filter_as_reason(path, fs_stat, status)
|
||||
return FILTER_REASON.none
|
||||
end
|
||||
|
||||
if git(self, path, status.git_status) then
|
||||
if git(self, path, status.project) then
|
||||
return FILTER_REASON.git
|
||||
elseif buf(self, path, status.bufinfo) then
|
||||
return FILTER_REASON.buf
|
||||
|
||||
@@ -59,7 +59,7 @@ function Explorer:create(path)
|
||||
|
||||
local o = RootNode:create(explorer_placeholder, path, "..", nil)
|
||||
|
||||
o = self:new(o) --[[@as Explorer]]
|
||||
o = self:new(o)
|
||||
|
||||
o.explorer = o
|
||||
|
||||
@@ -69,7 +69,7 @@ function Explorer:create(path)
|
||||
o.open = true
|
||||
o.opts = config
|
||||
|
||||
o.sorters = Sorters:new(config)
|
||||
o.sorters = Sorters:create(config)
|
||||
o.renderer = Renderer:new(config, o)
|
||||
o.filters = Filters:new(config, o)
|
||||
o.live_filter = LiveFilter:new(config, o)
|
||||
@@ -187,9 +187,9 @@ function Explorer:expand(node)
|
||||
end
|
||||
|
||||
---@param node DirectoryNode
|
||||
---@param git_status table|nil
|
||||
---@param project GitProject?
|
||||
---@return Node[]?
|
||||
function Explorer:reload(node, git_status)
|
||||
function Explorer:reload(node, project)
|
||||
local cwd = node.link_to or node.absolute_path
|
||||
local handle = vim.loop.fs_scandir(cwd)
|
||||
if not handle then
|
||||
@@ -198,7 +198,7 @@ function Explorer:reload(node, git_status)
|
||||
|
||||
local profile = log.profile_start("reload %s", node.absolute_path)
|
||||
|
||||
local filter_status = self.filters:prepare(git_status)
|
||||
local filter_status = self.filters:prepare(project)
|
||||
|
||||
if node.group_next then
|
||||
node.nodes = { node.group_next }
|
||||
@@ -268,7 +268,7 @@ function Explorer:reload(node, git_status)
|
||||
end
|
||||
|
||||
node.nodes = vim.tbl_map(
|
||||
self:update_status(nodes_by_path, node_ignored, git_status),
|
||||
self:update_git_statuses(nodes_by_path, node_ignored, project),
|
||||
vim.tbl_filter(function(n)
|
||||
if remain_childs[n.absolute_path] then
|
||||
return remain_childs[n.absolute_path]
|
||||
@@ -282,7 +282,7 @@ function Explorer:reload(node, git_status)
|
||||
local single_child = node:single_child_directory()
|
||||
if config.renderer.group_empty and node.parent and single_child then
|
||||
node.group_next = single_child
|
||||
local ns = self:reload(single_child, git_status)
|
||||
local ns = self:reload(single_child, project)
|
||||
node.nodes = ns or {}
|
||||
log.profile_end(profile)
|
||||
return ns
|
||||
@@ -321,7 +321,7 @@ function Explorer:refresh_parent_nodes_for_path(path)
|
||||
local project = git.get_project(toplevel) or {}
|
||||
|
||||
self:reload(node, project)
|
||||
node:update_parent_statuses(project, toplevel)
|
||||
git.update_parent_projects(node, project, toplevel)
|
||||
end
|
||||
|
||||
log.profile_end(profile)
|
||||
@@ -331,19 +331,19 @@ end
|
||||
---@param node DirectoryNode
|
||||
function Explorer:_load(node)
|
||||
local cwd = node.link_to or node.absolute_path
|
||||
local git_status = git.load_project_status(cwd)
|
||||
self:explore(node, git_status, self)
|
||||
local project = git.load_project(cwd)
|
||||
self:explore(node, project, self)
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param nodes_by_path Node[]
|
||||
---@param node_ignored boolean
|
||||
---@param status table|nil
|
||||
---@return fun(node: Node): table
|
||||
function Explorer:update_status(nodes_by_path, node_ignored, status)
|
||||
---@param project GitProject?
|
||||
---@return fun(node: Node): Node
|
||||
function Explorer:update_git_statuses(nodes_by_path, node_ignored, project)
|
||||
return function(node)
|
||||
if nodes_by_path[node.absolute_path] then
|
||||
node:update_git_status(node_ignored, status)
|
||||
node:update_git_status(node_ignored, project)
|
||||
end
|
||||
return node
|
||||
end
|
||||
@@ -353,13 +353,13 @@ end
|
||||
---@param handle uv.uv_fs_t
|
||||
---@param cwd string
|
||||
---@param node DirectoryNode
|
||||
---@param git_status table
|
||||
---@param project GitProject
|
||||
---@param parent Explorer
|
||||
function Explorer:populate_children(handle, cwd, node, git_status, parent)
|
||||
function Explorer:populate_children(handle, cwd, node, project, parent)
|
||||
local node_ignored = node:is_git_ignored()
|
||||
local nodes_by_path = utils.bool_record(node.nodes, "absolute_path")
|
||||
|
||||
local filter_status = parent.filters:prepare(git_status)
|
||||
local filter_status = parent.filters:prepare(project)
|
||||
|
||||
node.hidden_stats = vim.tbl_deep_extend("force", node.hidden_stats or {}, {
|
||||
git = 0,
|
||||
@@ -388,7 +388,7 @@ function Explorer:populate_children(handle, cwd, node, git_status, parent)
|
||||
if child then
|
||||
table.insert(node.nodes, child)
|
||||
nodes_by_path[child.absolute_path] = true
|
||||
child:update_git_status(node_ignored, git_status)
|
||||
child:update_git_status(node_ignored, project)
|
||||
end
|
||||
else
|
||||
for reason, value in pairs(FILTER_REASON) do
|
||||
@@ -405,10 +405,10 @@ end
|
||||
|
||||
---@private
|
||||
---@param node DirectoryNode
|
||||
---@param status table
|
||||
---@param project GitProject
|
||||
---@param parent Explorer
|
||||
---@return Node[]|nil
|
||||
function Explorer:explore(node, status, parent)
|
||||
function Explorer:explore(node, project, parent)
|
||||
local cwd = node.link_to or node.absolute_path
|
||||
local handle = vim.loop.fs_scandir(cwd)
|
||||
if not handle then
|
||||
@@ -417,15 +417,15 @@ function Explorer:explore(node, status, parent)
|
||||
|
||||
local profile = log.profile_start("explore %s", node.absolute_path)
|
||||
|
||||
self:populate_children(handle, cwd, node, status, parent)
|
||||
self:populate_children(handle, cwd, node, project, parent)
|
||||
|
||||
local is_root = not node.parent
|
||||
local single_child = node:single_child_directory()
|
||||
if config.renderer.group_empty and not is_root and single_child then
|
||||
local child_cwd = single_child.link_to or single_child.absolute_path
|
||||
local child_status = git.load_project_status(child_cwd)
|
||||
local child_project = git.load_project(child_cwd)
|
||||
node.group_next = single_child
|
||||
local ns = self:explore(single_child, child_status, parent)
|
||||
local ns = self:explore(single_child, child_project, parent)
|
||||
node.nodes = ns or {}
|
||||
|
||||
log.profile_end(profile)
|
||||
@@ -440,7 +440,7 @@ function Explorer:explore(node, status, parent)
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param projects table
|
||||
---@param projects GitProject[]
|
||||
function Explorer:refresh_nodes(projects)
|
||||
Iterator.builder({ self })
|
||||
:applier(function(n)
|
||||
@@ -463,7 +463,7 @@ function Explorer:reload_explorer()
|
||||
end
|
||||
event_running = true
|
||||
|
||||
local projects = git.reload()
|
||||
local projects = git.reload_all_projects()
|
||||
self:refresh_nodes(projects)
|
||||
if view.is_visible() then
|
||||
self.renderer:draw()
|
||||
@@ -477,8 +477,8 @@ function Explorer:reload_git()
|
||||
end
|
||||
event_running = true
|
||||
|
||||
local projects = git.reload()
|
||||
self:reload_node_status(projects)
|
||||
local projects = git.reload_all_projects()
|
||||
git.reload_node_status(self, projects)
|
||||
self.renderer:draw()
|
||||
event_running = false
|
||||
end
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
local Class = require("nvim-tree.class")
|
||||
local DirectoryNode = require("nvim-tree.node.directory")
|
||||
|
||||
local C = {}
|
||||
|
||||
---@class Sorter
|
||||
local Sorter = {}
|
||||
---@class (exact) SorterCfg
|
||||
---@field sorter string|fun(nodes: Node[])
|
||||
---@field folders_first boolean
|
||||
---@field files_first boolean
|
||||
|
||||
function Sorter:new(opts)
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.config = vim.deepcopy(opts.sort)
|
||||
---@class (exact) Sorter: Class
|
||||
---@field cfg SorterCfg
|
||||
---@field user fun(nodes: Node[])?
|
||||
---@field pre string?
|
||||
local Sorter = Class:new()
|
||||
|
||||
if type(o.config.sorter) == "function" then
|
||||
o.user = o.config.sorter
|
||||
---@param opts table user options
|
||||
---@return Sorter
|
||||
function Sorter:create(opts)
|
||||
---@type Sorter
|
||||
local o = {
|
||||
cfg = vim.deepcopy(opts.sort),
|
||||
}
|
||||
o = self:new(o)
|
||||
|
||||
if type(o.cfg.sorter) == "function" then
|
||||
o.user = o.cfg.sorter --[[@as fun(nodes: Node[])]]
|
||||
elseif type(o.cfg.sorter) == "string" then
|
||||
o.pre = o.cfg.sorter --[[@as string]]
|
||||
end
|
||||
return o
|
||||
end
|
||||
@@ -20,7 +36,7 @@ end
|
||||
---@return fun(a: Node, b: Node): boolean
|
||||
function Sorter:get_comparator(sorter)
|
||||
return function(a, b)
|
||||
return (C[sorter] or C.name)(a, b, self.config)
|
||||
return (C[sorter] or C.name)(a, b, self.cfg)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,17 +57,17 @@ end
|
||||
---Evaluate `sort.folders_first` and `sort.files_first`
|
||||
---@param a Node
|
||||
---@param b Node
|
||||
---@param cfg table
|
||||
---@param cfg SorterCfg
|
||||
---@return boolean|nil
|
||||
local function folders_or_files_first(a, b, cfg)
|
||||
if not (cfg.folders_first or cfg.files_first) then
|
||||
return
|
||||
end
|
||||
|
||||
if not a.nodes and b.nodes then
|
||||
if not a:is(DirectoryNode) and b:is(DirectoryNode) then
|
||||
-- file <> folder
|
||||
return cfg.files_first
|
||||
elseif a.nodes and not b.nodes then
|
||||
elseif a:is(DirectoryNode) and not b:is(DirectoryNode) then
|
||||
-- folder <> file
|
||||
return not cfg.files_first
|
||||
end
|
||||
@@ -157,15 +173,15 @@ function Sorter:sort(t)
|
||||
end
|
||||
|
||||
split_merge(t, 1, #t, mini_comparator) -- sort by user order
|
||||
else
|
||||
split_merge(t, 1, #t, self:get_comparator(self.config.sorter))
|
||||
elseif self.pre then
|
||||
split_merge(t, 1, #t, self:get_comparator(self.pre))
|
||||
end
|
||||
end
|
||||
|
||||
---@param a Node
|
||||
---@param b Node
|
||||
---@param ignorecase boolean|nil
|
||||
---@param cfg table
|
||||
---@param cfg SorterCfg
|
||||
---@return boolean
|
||||
local function node_comparator_name_ignorecase_or_not(a, b, ignorecase, cfg)
|
||||
if not (a and b) then
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local log = require("nvim-tree.log")
|
||||
local git = require("nvim-tree.git")
|
||||
local utils = require("nvim-tree.utils")
|
||||
local Watcher = require("nvim-tree.watcher").Watcher
|
||||
|
||||
@@ -65,9 +66,10 @@ function M.create_watcher(node)
|
||||
return nil
|
||||
end
|
||||
|
||||
---@param watcher Watcher
|
||||
local function callback(watcher)
|
||||
log.line("watcher", "node event scheduled refresh %s", watcher.context)
|
||||
utils.debounce(watcher.context, M.config.filesystem_watchers.debounce_delay, function()
|
||||
log.line("watcher", "node event scheduled refresh %s", watcher.data.context)
|
||||
utils.debounce(watcher.data.context, M.config.filesystem_watchers.debounce_delay, function()
|
||||
if watcher.destroyed then
|
||||
return
|
||||
end
|
||||
@@ -76,12 +78,12 @@ function M.create_watcher(node)
|
||||
else
|
||||
log.line("watcher", "node event executing refresh '%s'", node.absolute_path)
|
||||
end
|
||||
node:refresh()
|
||||
git.refresh_dir(node)
|
||||
end)
|
||||
end
|
||||
|
||||
M.uid = M.uid + 1
|
||||
return Watcher:new(path, nil, callback, {
|
||||
return Watcher:create(path, nil, callback, {
|
||||
context = "explorer:watch:" .. path .. ":" .. M.uid,
|
||||
})
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user