fix(git): git folder fixes and improvements (#1809)
* coding style
* outlined git.show_on_open_dirs behavior
* show some icon on opendir even if show_on_open_dir=false
and show all children's status on parent
* fixed renamed icon not showing
* sorted icons
* removed DU from deleted as file will show up in tree
* fixed update_git_status in reloaders not tested
* fixed Api.git.reload()
Tested update_git_status in reloaders.lua
* sort icon only if not git signcolumn
* fixed crashing when root dir isn't git dir
* made git.show_on_dirs doc more concise
* git_statuses -> git_status for consistency
* explorer/common.lua -> explorer/node.lua
* fixed #1784 conflict
* don't order icons
* Revert "don't order icons"
This reverts commit 23f6276ef7.
This commit is contained in:
parent
89c79cb33b
commit
29788cc32a
@ -599,7 +599,7 @@ Git integration with icons and colors.
|
|||||||
Type: `boolean`, Default: `true`
|
Type: `boolean`, Default: `true`
|
||||||
|
|
||||||
*nvim-tree.git.show_on_open_dirs*
|
*nvim-tree.git.show_on_open_dirs*
|
||||||
Show status icons on directories that are open.
|
Show status icons of children on directories that are open.
|
||||||
Only relevant when `git.show_on_dirs` is `true`.
|
Only relevant when `git.show_on_dirs` is `true`.
|
||||||
Type: `boolean`, Default: `true`
|
Type: `boolean`, Default: `true`
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ local utils = require "nvim-tree.utils"
|
|||||||
local view = require "nvim-tree.view"
|
local view = require "nvim-tree.view"
|
||||||
local core = require "nvim-tree.core"
|
local core = require "nvim-tree.core"
|
||||||
local lib = require "nvim-tree.lib"
|
local lib = require "nvim-tree.lib"
|
||||||
local explorer_common = require "nvim-tree.explorer.common"
|
local explorer_node = require "nvim-tree.explorer.node"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ function M.fn(where, what)
|
|||||||
for line, node in pairs(nodes_by_line) do
|
for line, node in pairs(nodes_by_line) do
|
||||||
local valid = false
|
local valid = false
|
||||||
if what == "git" then
|
if what == "git" then
|
||||||
valid = explorer_common.shows_git_status(node)
|
valid = explorer_node.get_git_status(node) ~= nil
|
||||||
elseif what == "diag" then
|
elseif what == "diag" then
|
||||||
valid = node.diag_status ~= nil
|
valid = node.diag_status ~= nil
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,6 +3,7 @@ local view = require "nvim-tree.view"
|
|||||||
local renderer = require "nvim-tree.renderer"
|
local renderer = require "nvim-tree.renderer"
|
||||||
local explorer_module = require "nvim-tree.explorer"
|
local explorer_module = require "nvim-tree.explorer"
|
||||||
local core = require "nvim-tree.core"
|
local core = require "nvim-tree.core"
|
||||||
|
local explorer_node = require "nvim-tree.explorer.node"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@ -21,11 +22,7 @@ function M.reload_node_status(parent_node, projects)
|
|||||||
local project_root = git.get_project_root(parent_node.absolute_path)
|
local project_root = git.get_project_root(parent_node.absolute_path)
|
||||||
local status = projects[project_root] or {}
|
local status = projects[project_root] or {}
|
||||||
for _, node in ipairs(parent_node.nodes) do
|
for _, node in ipairs(parent_node.nodes) do
|
||||||
if node.nodes then
|
explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), status)
|
||||||
node.git_status = status.dirs and status.dirs[node.absolute_path]
|
|
||||||
else
|
|
||||||
node.git_status = status.files and status.files[node.absolute_path]
|
|
||||||
end
|
|
||||||
if node.nodes and #node.nodes > 0 then
|
if node.nodes and #node.nodes > 0 then
|
||||||
M.reload_node_status(node, projects)
|
M.reload_node_status(node, projects)
|
||||||
end
|
end
|
||||||
@ -50,7 +47,7 @@ function M.reload_explorer(_, unloaded_bufnr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.reload_git()
|
function M.reload_git()
|
||||||
if not core.get_explorer() or not git.config.enable or event_running then
|
if not core.get_explorer() or not git.config.git.enable or event_running then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
event_running = true
|
event_running = true
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
local M = {}
|
|
||||||
|
|
||||||
local function get_dir_git_status(parent_ignored, status, absolute_path)
|
|
||||||
if parent_ignored then
|
|
||||||
return "!!"
|
|
||||||
end
|
|
||||||
|
|
||||||
local file_status = status.files and status.files[absolute_path]
|
|
||||||
if file_status then
|
|
||||||
return file_status
|
|
||||||
end
|
|
||||||
|
|
||||||
return status.dirs and status.dirs[absolute_path]
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_git_status(parent_ignored, status, absolute_path)
|
|
||||||
return parent_ignored and "!!" or status.files and status.files[absolute_path]
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.has_one_child_folder(node)
|
|
||||||
return #node.nodes == 1 and node.nodes[1].nodes and vim.loop.fs_access(node.nodes[1].absolute_path, "R")
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.update_git_status(node, parent_ignored, status)
|
|
||||||
-- status of the node's absolute path
|
|
||||||
if node.nodes then
|
|
||||||
node.git_status = get_dir_git_status(parent_ignored, status, node.absolute_path)
|
|
||||||
else
|
|
||||||
node.git_status = get_git_status(parent_ignored, status, node.absolute_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- status of the link target, if the link itself is not dirty
|
|
||||||
if node.link_to and not node.git_status then
|
|
||||||
if node.nodes then
|
|
||||||
node.git_status = get_dir_git_status(parent_ignored, status, node.link_to)
|
|
||||||
else
|
|
||||||
node.git_status = get_git_status(parent_ignored, status, node.link_to)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.shows_git_status(node)
|
|
||||||
if not node.git_status then
|
|
||||||
-- status doesn't exist
|
|
||||||
return false
|
|
||||||
elseif not node.nodes then
|
|
||||||
-- status exist and is a file
|
|
||||||
return true
|
|
||||||
elseif not node.open then
|
|
||||||
-- status exist, is a closed dir
|
|
||||||
return M.config.git.show_on_dirs
|
|
||||||
else
|
|
||||||
-- status exist, is a open dir
|
|
||||||
return M.config.git.show_on_dirs and M.config.git.show_on_open_dirs
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.node_destroy(node)
|
|
||||||
if not node then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if node.watcher then
|
|
||||||
node.watcher:destroy()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.setup(opts)
|
|
||||||
M.config = {
|
|
||||||
git = opts.git,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
local utils = require "nvim-tree.utils"
|
local utils = require "nvim-tree.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 explorer_node = require "nvim-tree.explorer.node"
|
||||||
local sorters = require "nvim-tree.explorer.sorters"
|
local sorters = require "nvim-tree.explorer.sorters"
|
||||||
local filters = require "nvim-tree.explorer.filters"
|
local filters = require "nvim-tree.explorer.filters"
|
||||||
local live_filter = require "nvim-tree.live-filter"
|
local live_filter = require "nvim-tree.live-filter"
|
||||||
@ -14,7 +14,7 @@ local function get_type_from(type_, cwd)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function populate_children(handle, cwd, node, git_status)
|
local function populate_children(handle, cwd, node, git_status)
|
||||||
local node_ignored = node.git_status == "!!"
|
local node_ignored = explorer_node.is_git_ignored(node)
|
||||||
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)
|
local filter_status = filters.prepare(git_status)
|
||||||
while true do
|
while true do
|
||||||
@ -40,7 +40,7 @@ local function populate_children(handle, cwd, node, git_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, git_status)
|
explorer_node.update_git_status(child, node_ignored, git_status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -68,7 +68,7 @@ function M.explore(node, status)
|
|||||||
populate_children(handle, cwd, node, status)
|
populate_children(handle, cwd, node, status)
|
||||||
|
|
||||||
local is_root = not node.parent
|
local is_root = not node.parent
|
||||||
local child_folder_only = common.has_one_child_folder(node) and node.nodes[1]
|
local child_folder_only = explorer_node.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.explore(child_folder_only, status)
|
local ns = M.explore(child_folder_only, status)
|
||||||
|
|||||||
@ -24,7 +24,9 @@ local function git(path, git_status)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- default status to clean
|
-- default status to clean
|
||||||
local status = git_status.files[path] or git_status.dirs[path] or " "
|
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]
|
||||||
|
|
||||||
-- filter ignored; overrides clean as they are effectively dirty
|
-- filter ignored; overrides clean as they are effectively dirty
|
||||||
if M.config.filter_git_ignored and status == "!!" then
|
if M.config.filter_git_ignored and status == "!!" then
|
||||||
@ -32,7 +34,7 @@ local function git(path, git_status)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- filter clean
|
-- filter clean
|
||||||
if M.config.filter_git_clean and status == " " then
|
if M.config.filter_git_clean and not status then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
local git = require "nvim-tree.git"
|
local git = require "nvim-tree.git"
|
||||||
local watch = require "nvim-tree.explorer.watch"
|
local watch = require "nvim-tree.explorer.watch"
|
||||||
local common = require "nvim-tree.explorer.common"
|
local explorer_node = require "nvim-tree.explorer.node"
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@ -24,8 +24,8 @@ end
|
|||||||
|
|
||||||
function Explorer:_load(node)
|
function Explorer:_load(node)
|
||||||
local cwd = node.link_to or node.absolute_path
|
local cwd = node.link_to or node.absolute_path
|
||||||
local git_statuses = git.load_project_status(cwd)
|
local git_status = git.load_project_status(cwd)
|
||||||
M.explore(node, git_statuses)
|
M.explore(node, git_status)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Explorer:expand(node)
|
function Explorer:expand(node)
|
||||||
@ -34,7 +34,7 @@ end
|
|||||||
|
|
||||||
function Explorer:destroy()
|
function Explorer:destroy()
|
||||||
local function iterate(node)
|
local function iterate(node)
|
||||||
common.node_destroy(node)
|
explorer_node.node_destroy(node)
|
||||||
if node.nodes then
|
if node.nodes then
|
||||||
for _, child in pairs(node.nodes) do
|
for _, child in pairs(node.nodes) do
|
||||||
iterate(child)
|
iterate(child)
|
||||||
@ -45,7 +45,7 @@ function Explorer:destroy()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
require("nvim-tree.explorer.common").setup(opts)
|
require("nvim-tree.explorer.node").setup(opts)
|
||||||
require("nvim-tree.explorer.explore").setup(opts)
|
require("nvim-tree.explorer.explore").setup(opts)
|
||||||
require("nvim-tree.explorer.filters").setup(opts)
|
require("nvim-tree.explorer.filters").setup(opts)
|
||||||
require("nvim-tree.explorer.sorters").setup(opts)
|
require("nvim-tree.explorer.sorters").setup(opts)
|
||||||
|
|||||||
133
lua/nvim-tree/explorer/node.lua
Normal file
133
lua/nvim-tree/explorer/node.lua
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- node.git_status structure:
|
||||||
|
-- {
|
||||||
|
-- file = string | nil,
|
||||||
|
-- dir = {
|
||||||
|
-- direct = { string } | nil,
|
||||||
|
-- indirect = { string } | nil,
|
||||||
|
-- } | nil,
|
||||||
|
-- }
|
||||||
|
|
||||||
|
local function get_dir_git_status(parent_ignored, status, absolute_path)
|
||||||
|
if parent_ignored then
|
||||||
|
return { file = "!!" }
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
file = status.files and status.files[absolute_path],
|
||||||
|
dir = status.dirs and {
|
||||||
|
direct = status.dirs.direct[absolute_path],
|
||||||
|
indirect = status.dirs.indirect[absolute_path],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_git_status(parent_ignored, status, absolute_path)
|
||||||
|
local file_status = parent_ignored and "!!" or status.files and status.files[absolute_path]
|
||||||
|
return { file = file_status }
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.has_one_child_folder(node)
|
||||||
|
return #node.nodes == 1 and node.nodes[1].nodes and vim.loop.fs_access(node.nodes[1].absolute_path, "R")
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.update_git_status(node, parent_ignored, status)
|
||||||
|
local get_status
|
||||||
|
if node.nodes then
|
||||||
|
get_status = get_dir_git_status
|
||||||
|
else
|
||||||
|
get_status = get_git_status
|
||||||
|
end
|
||||||
|
|
||||||
|
-- status of the node's absolute path
|
||||||
|
node.git_status = get_status(parent_ignored, status, node.absolute_path)
|
||||||
|
|
||||||
|
-- status of the link target, if the link itself is not dirty
|
||||||
|
if node.link_to and not node.git_status then
|
||||||
|
node.git_status = get_status(parent_ignored, status, node.link_to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.get_git_status(node)
|
||||||
|
local git_status = node.git_status
|
||||||
|
if not git_status then
|
||||||
|
-- status doesn't exist
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if not node.nodes then
|
||||||
|
-- file
|
||||||
|
return git_status.file and { git_status.file }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- dir
|
||||||
|
if not M.config.git.show_on_dirs then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local status = {}
|
||||||
|
if not node.open or M.config.git.show_on_open_dirs then
|
||||||
|
-- dir is closed or we should show on open_dirs
|
||||||
|
if git_status.file ~= nil then
|
||||||
|
table.insert(status, git_status.file)
|
||||||
|
end
|
||||||
|
if git_status.dir ~= nil then
|
||||||
|
if git_status.dir.direct ~= nil then
|
||||||
|
for _, s in pairs(node.git_status.dir.direct) do
|
||||||
|
table.insert(status, s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if git_status.dir.indirect ~= nil then
|
||||||
|
for _, s in pairs(node.git_status.dir.indirect) do
|
||||||
|
table.insert(status, s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- dir is open and we shouldn't show on open_dirs
|
||||||
|
if git_status.file ~= nil then
|
||||||
|
table.insert(status, git_status.file)
|
||||||
|
end
|
||||||
|
if git_status.dir ~= nil and git_status.dir.direct ~= nil then
|
||||||
|
local deleted = {
|
||||||
|
[" D"] = true,
|
||||||
|
["D "] = true,
|
||||||
|
["RD"] = true,
|
||||||
|
["DD"] = true,
|
||||||
|
}
|
||||||
|
for _, s in pairs(node.git_status.dir.direct) do
|
||||||
|
if deleted[s] then
|
||||||
|
table.insert(status, s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #status == 0 then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return status
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.is_git_ignored(node)
|
||||||
|
return node.git_status and node.git_status.file == "!!"
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.node_destroy(node)
|
||||||
|
if not node then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if node.watcher then
|
||||||
|
node.watcher:destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.setup(opts)
|
||||||
|
M.config = {
|
||||||
|
git = opts.git,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@ -1,6 +1,6 @@
|
|||||||
local utils = require "nvim-tree.utils"
|
local utils = require "nvim-tree.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 explorer_node = require "nvim-tree.explorer.node"
|
||||||
local filters = require "nvim-tree.explorer.filters"
|
local filters = require "nvim-tree.explorer.filters"
|
||||||
local sorters = require "nvim-tree.explorer.sorters"
|
local sorters = require "nvim-tree.explorer.sorters"
|
||||||
local live_filter = require "nvim-tree.live-filter"
|
local live_filter = require "nvim-tree.live-filter"
|
||||||
@ -15,7 +15,7 @@ local M = {}
|
|||||||
local function update_status(nodes_by_path, node_ignored, status)
|
local function update_status(nodes_by_path, node_ignored, status)
|
||||||
return function(node)
|
return function(node)
|
||||||
if nodes_by_path[node.absolute_path] then
|
if nodes_by_path[node.absolute_path] then
|
||||||
common.update_git_status(node, node_ignored, status)
|
explorer_node.update_git_status(node, node_ignored, status)
|
||||||
end
|
end
|
||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
@ -29,7 +29,7 @@ end
|
|||||||
|
|
||||||
local function update_parent_statuses(node, project, root)
|
local function update_parent_statuses(node, project, root)
|
||||||
while project and node and node.absolute_path ~= root do
|
while project and node and node.absolute_path ~= root do
|
||||||
common.update_git_status(node, false, project)
|
explorer_node.update_git_status(node, false, project)
|
||||||
node = node.parent
|
node = node.parent
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -53,7 +53,7 @@ function M.reload(node, git_status, unloaded_bufnr)
|
|||||||
|
|
||||||
local child_names = {}
|
local child_names = {}
|
||||||
|
|
||||||
local node_ignored = node.git_status == "!!"
|
local node_ignored = explorer_node.is_git_ignored(node)
|
||||||
local nodes_by_path = utils.key_by(node.nodes, "absolute_path")
|
local nodes_by_path = utils.key_by(node.nodes, "absolute_path")
|
||||||
while true do
|
while true do
|
||||||
local name, t = utils.fs_scandir_next_profiled(handle, cwd)
|
local name, t = utils.fs_scandir_next_profiled(handle, cwd)
|
||||||
@ -82,7 +82,7 @@ function M.reload(node, git_status, unloaded_bufnr)
|
|||||||
|
|
||||||
if n.type ~= t then
|
if n.type ~= t then
|
||||||
utils.array_remove(node.nodes, n)
|
utils.array_remove(node.nodes, n)
|
||||||
common.node_destroy(n)
|
explorer_node.node_destroy(n)
|
||||||
nodes_by_path[abs] = nil
|
nodes_by_path[abs] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -119,14 +119,14 @@ function M.reload(node, git_status, unloaded_bufnr)
|
|||||||
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]
|
||||||
else
|
else
|
||||||
common.node_destroy(n)
|
explorer_node.node_destroy(n)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end, node.nodes)
|
end, node.nodes)
|
||||||
)
|
)
|
||||||
|
|
||||||
local is_root = not node.parent
|
local is_root = not node.parent
|
||||||
local child_folder_only = common.has_one_child_folder(node) and node.nodes[1]
|
local child_folder_only = explorer_node.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, git_status)
|
local ns = M.reload(child_folder_only, git_status)
|
||||||
|
|||||||
@ -4,6 +4,7 @@ local git_utils = require "nvim-tree.git.utils"
|
|||||||
local Runner = require "nvim-tree.git.runner"
|
local Runner = require "nvim-tree.git.runner"
|
||||||
local Watcher = require("nvim-tree.watcher").Watcher
|
local Watcher = require("nvim-tree.watcher").Watcher
|
||||||
local Iterator = require "nvim-tree.iterators.node-iterator"
|
local Iterator = require "nvim-tree.iterators.node-iterator"
|
||||||
|
local explorer_node = require "nvim-tree.explorer.node"
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
config = {},
|
config = {},
|
||||||
@ -103,19 +104,13 @@ local function reload_tree_at(project_root)
|
|||||||
end
|
end
|
||||||
|
|
||||||
M.reload_project(project_root)
|
M.reload_project(project_root)
|
||||||
local project = M.get_project(project_root)
|
local git_status = M.get_project(project_root)
|
||||||
|
|
||||||
local project_files = project.files and project.files or {}
|
|
||||||
local project_dirs = project.dirs and project.dirs or {}
|
|
||||||
|
|
||||||
Iterator.builder(root_node.nodes)
|
Iterator.builder(root_node.nodes)
|
||||||
:hidden()
|
:hidden()
|
||||||
:applier(function(node)
|
:applier(function(node)
|
||||||
local parent_ignored = node.parent.git_status == "!!"
|
local parent_ignored = explorer_node.is_git_ignored(node.parent)
|
||||||
node.git_status = project_dirs[node.absolute_path] or project_files[node.absolute_path]
|
explorer_node.update_git_status(node, parent_ignored, git_status)
|
||||||
if not node.git_status and parent_ignored then
|
|
||||||
node.git_status = "!!"
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
:recursor(function(node)
|
:recursor(function(node)
|
||||||
return node.nodes and #node.nodes > 0 and node.nodes
|
return node.nodes and #node.nodes > 0 and node.nodes
|
||||||
|
|||||||
@ -55,24 +55,43 @@ function M.should_show_untracked(cwd)
|
|||||||
return untracked[cwd]
|
return untracked[cwd]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function nil_insert(t, k)
|
||||||
|
t = t or {}
|
||||||
|
t[k] = true
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
function M.file_status_to_dir_status(status, cwd)
|
function M.file_status_to_dir_status(status, cwd)
|
||||||
local dirs = {}
|
local direct = {}
|
||||||
for p, s in pairs(status) do
|
for p, s in pairs(status) do
|
||||||
if s ~= "!!" then
|
if s ~= "!!" then
|
||||||
local modified = vim.fn.fnamemodify(p, ":h")
|
local modified = vim.fn.fnamemodify(p, ":h")
|
||||||
dirs[modified] = s
|
direct[modified] = nil_insert(direct[modified], s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for dirname, s in pairs(dirs) do
|
local indirect = {}
|
||||||
local modified = dirname
|
for dirname, statuses in pairs(direct) do
|
||||||
while modified ~= cwd and modified ~= "/" do
|
for s, _ in pairs(statuses) do
|
||||||
modified = vim.fn.fnamemodify(modified, ":h")
|
local modified = dirname
|
||||||
dirs[modified] = s
|
while modified ~= cwd and modified ~= "/" do
|
||||||
|
modified = vim.fn.fnamemodify(modified, ":h")
|
||||||
|
indirect[modified] = nil_insert(indirect[modified], s)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return dirs
|
local r = { indirect = indirect, direct = direct }
|
||||||
|
for _, d in pairs(r) do
|
||||||
|
for dirname, statuses in pairs(d) do
|
||||||
|
local new_statuses = {}
|
||||||
|
for s, _ in pairs(statuses) do
|
||||||
|
table.insert(new_statuses, s)
|
||||||
|
end
|
||||||
|
d[dirname] = new_statuses
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@ -250,10 +250,17 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
|
|||||||
local git_highlight = git.get_highlight(node)
|
local git_highlight = git.get_highlight(node)
|
||||||
local git_icons_tbl = git.get_icons(node)
|
local git_icons_tbl = git.get_icons(node)
|
||||||
|
|
||||||
if self.is_git_sign and git_icons_tbl and #git_icons_tbl > 0 then
|
if git_icons_tbl and #git_icons_tbl > 0 then
|
||||||
local git_info = git_icons_tbl[1]
|
if self.is_git_sign then
|
||||||
table.insert(self.signs, { sign = git_info.hl, lnum = self.index + 1 })
|
local git_info = git_icons_tbl[1]
|
||||||
git_icons_tbl = {}
|
table.insert(self.signs, { sign = git_info.hl, lnum = self.index + 1 })
|
||||||
|
git_icons_tbl = {}
|
||||||
|
else
|
||||||
|
-- sort icons so it looks slightly better
|
||||||
|
table.sort(git_icons_tbl, function(a, b)
|
||||||
|
return a.ord < b.ord
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local is_folder = node.nodes ~= nil
|
local is_folder = node.nodes ~= nil
|
||||||
|
|||||||
@ -1,68 +1,51 @@
|
|||||||
local notify = require "nvim-tree.notify"
|
local notify = require "nvim-tree.notify"
|
||||||
local explorer_common = require "nvim-tree.explorer.common"
|
local explorer_node = require "nvim-tree.explorer.node"
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
SIGN_GROUP = "NvimTreeGitSigns",
|
SIGN_GROUP = "NvimTreeGitSigns",
|
||||||
}
|
}
|
||||||
|
|
||||||
local function build_icons_table(i)
|
local function build_icons_table(i)
|
||||||
|
local icons = {
|
||||||
|
staged = { icon = i.staged, hl = "NvimTreeGitStaged", ord = 1 },
|
||||||
|
unstaged = { icon = i.unstaged, hl = "NvimTreeGitDirty", ord = 2 },
|
||||||
|
renamed = { icon = i.renamed, hl = "NvimTreeGitRenamed", ord = 3 },
|
||||||
|
deleted = { icon = i.deleted, hl = "NvimTreeGitDeleted", ord = 4 },
|
||||||
|
unmerged = { icon = i.unmerged, hl = "NvimTreeGitMerge", ord = 5 },
|
||||||
|
untracked = { icon = i.untracked, hl = "NvimTreeGitNew", ord = 6 },
|
||||||
|
ignored = { icon = i.ignored, hl = "NvimTreeGitIgnored", ord = 7 },
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
["M "] = { { icon = i.staged, hl = "NvimTreeGitStaged" } },
|
["M "] = { icons.staged },
|
||||||
[" M"] = { { icon = i.unstaged, hl = "NvimTreeGitDirty" } },
|
[" M"] = { icons.unstaged },
|
||||||
["C "] = { { icon = i.staged, hl = "NvimTreeGitStaged" } },
|
["C "] = { icons.staged },
|
||||||
[" C"] = { { icon = i.unstaged, hl = "NvimTreeGitDirty" } },
|
[" C"] = { icons.unstaged },
|
||||||
["CM"] = { { icon = i.unstaged, hl = "NvimTreeGitDirty" } },
|
["CM"] = { icons.unstaged },
|
||||||
[" T"] = { { icon = i.unstaged, hl = "NvimTreeGitDirty" } },
|
[" T"] = { icons.unstaged },
|
||||||
["T "] = { { icon = i.staged, hl = "NvimTreeGitStaged" } },
|
["T "] = { icons.staged },
|
||||||
["MM"] = {
|
["MM"] = { icons.staged, icons.unstaged },
|
||||||
{ icon = i.staged, hl = "NvimTreeGitStaged" },
|
["MD"] = { icons.staged },
|
||||||
{ icon = i.unstaged, hl = "NvimTreeGitDirty" },
|
["A "] = { icons.staged },
|
||||||
},
|
["AD"] = { icons.staged },
|
||||||
["MD"] = {
|
[" A"] = { icons.untracked },
|
||||||
{ icon = i.staged, hl = "NvimTreeGitStaged" },
|
|
||||||
},
|
|
||||||
["A "] = {
|
|
||||||
{ icon = i.staged, hl = "NvimTreeGitStaged" },
|
|
||||||
},
|
|
||||||
["AD"] = {
|
|
||||||
{ icon = i.staged, hl = "NvimTreeGitStaged" },
|
|
||||||
},
|
|
||||||
[" A"] = {
|
|
||||||
{ icon = i.untracked, hl = "NvimTreeGitNew" },
|
|
||||||
},
|
|
||||||
-- not sure about this one
|
-- not sure about this one
|
||||||
["AA"] = {
|
["AA"] = { icons.unmerged, icons.untracked },
|
||||||
{ icon = i.unmerged, hl = "NvimTreeGitMerge" },
|
["AU"] = { icons.unmerged, icons.untracked },
|
||||||
{ icon = i.untracked, hl = "NvimTreeGitNew" },
|
["AM"] = { icons.staged, icons.unstaged },
|
||||||
},
|
["??"] = { icons.untracked },
|
||||||
["AU"] = {
|
["R "] = { icons.renamed },
|
||||||
{ icon = i.unmerged, hl = "NvimTreeGitMerge" },
|
[" R"] = { icons.renamed },
|
||||||
{ icon = i.untracked, hl = "NvimTreeGitNew" },
|
["RM"] = { icons.unstaged, icons.renamed },
|
||||||
},
|
["UU"] = { icons.unmerged },
|
||||||
["AM"] = {
|
["UD"] = { icons.unmerged },
|
||||||
{ icon = i.staged, hl = "NvimTreeGitStaged" },
|
["UA"] = { icons.unmerged },
|
||||||
{ icon = i.unstaged, hl = "NvimTreeGitDirty" },
|
[" D"] = { icons.deleted },
|
||||||
},
|
["D "] = { icons.deleted },
|
||||||
["??"] = { { icon = i.untracked, hl = "NvimTreeGitNew" } },
|
["RD"] = { icons.deleted },
|
||||||
["R "] = { { icon = i.renamed, hl = "NvimTreeGitRenamed" } },
|
["DD"] = { icons.deleted },
|
||||||
[" R"] = { { icon = i.renamed, hl = "NvimTreeGitRenamed" } },
|
["DU"] = { icons.deleted, icons.unmerged },
|
||||||
["RM"] = {
|
["!!"] = { icons.ignored },
|
||||||
{ icon = i.unstaged, hl = "NvimTreeGitDirty" },
|
dirty = { icons.unstaged },
|
||||||
{ icon = i.renamed, hl = "NvimTreeGitRenamed" },
|
|
||||||
},
|
|
||||||
["UU"] = { { icon = i.unmerged, hl = "NvimTreeGitMerge" } },
|
|
||||||
["UD"] = { { icon = i.unmerged, hl = "NvimTreeGitMerge" } },
|
|
||||||
["UA"] = { { icon = i.unmerged, hl = "NvimTreeGitMerge" } },
|
|
||||||
[" D"] = { { icon = i.deleted, hl = "NvimTreeGitDeleted" } },
|
|
||||||
["D "] = { { icon = i.deleted, hl = "NvimTreeGitDeleted" } },
|
|
||||||
["RD"] = { { icon = i.deleted, hl = "NvimTreeGitDeleted" } },
|
|
||||||
["DD"] = { { icon = i.deleted, hl = "NvimTreeGitDeleted" } },
|
|
||||||
["DU"] = {
|
|
||||||
{ icon = i.deleted, hl = "NvimTreeGitDeleted" },
|
|
||||||
{ icon = i.unmerged, hl = "NvimTreeGitMerge" },
|
|
||||||
},
|
|
||||||
["!!"] = { { icon = i.ignored, hl = "NvimTreeGitIgnored" } },
|
|
||||||
dirty = { { icon = i.unstaged, hl = "NvimTreeGitDirty" } },
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -77,20 +60,32 @@ local function warn_status(git_status)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function get_icons_(node)
|
local function get_icons_(node)
|
||||||
if not explorer_common.shows_git_status(node) then
|
local git_status = explorer_node.get_git_status(node)
|
||||||
|
if git_status == nil then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local git_status = node.git_status
|
local inserted = {}
|
||||||
local icons = M.git_icons[git_status]
|
local iconss = {}
|
||||||
if not icons then
|
|
||||||
if not M.config.highlight_git then
|
for _, s in pairs(git_status) do
|
||||||
warn_status(git_status)
|
local icons = M.git_icons[s]
|
||||||
|
if not icons then
|
||||||
|
if not M.config.highlight_git then
|
||||||
|
warn_status(s)
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, icon in pairs(icons) do
|
||||||
|
if not inserted[icon] then
|
||||||
|
table.insert(iconss, icon)
|
||||||
|
inserted[icon] = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return icons
|
return iconss
|
||||||
end
|
end
|
||||||
|
|
||||||
local git_hl = {
|
local git_hl = {
|
||||||
@ -137,12 +132,12 @@ function M.setup_signs(i)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function get_highlight_(node)
|
local function get_highlight_(node)
|
||||||
local git_status = node.git_status
|
local git_status = explorer_node.get_git_status(node)
|
||||||
if not explorer_common.shows_git_status(node) then
|
if git_status == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
return git_hl[git_status]
|
return git_hl[git_status[1]]
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.setup(opts)
|
function M.setup(opts)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user