Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve git icons on directories #1809

Merged
merged 16 commits into from
Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ Git integration with icons and colors.
Type: `boolean`, Default: `true`

*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`.
Type: `boolean`, Default: `true`

Expand Down
4 changes: 2 additions & 2 deletions lua/nvim-tree/actions/moves/item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ local utils = require "nvim-tree.utils"
local view = require "nvim-tree.view"
local core = require "nvim-tree.core"
local lib = require "nvim-tree.lib"
local explorer_common = require "nvim-tree.explorer.common"
local explorer_node = require "nvim-tree.explorer.node"

local M = {}

Expand All @@ -15,7 +15,7 @@ function M.fn(where, what)
for line, node in pairs(nodes_by_line) do
local valid = false
if what == "git" then
valid = explorer_common.shows_git_status(node)
valid = explorer_node.get_git_status(node) ~= nil
elseif what == "diag" then
valid = node.diag_status ~= nil
end
Expand Down
9 changes: 3 additions & 6 deletions lua/nvim-tree/actions/reloaders/reloaders.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local view = require "nvim-tree.view"
local renderer = require "nvim-tree.renderer"
local explorer_module = require "nvim-tree.explorer"
local core = require "nvim-tree.core"
local explorer_node = require "nvim-tree.explorer.node"

local M = {}

Expand All @@ -21,11 +22,7 @@ function M.reload_node_status(parent_node, projects)
local project_root = git.get_project_root(parent_node.absolute_path)
local status = projects[project_root] or {}
for _, node in ipairs(parent_node.nodes) do
if node.nodes then
node.git_status = status.dirs and status.dirs[node.absolute_path]
else
node.git_status = status.files and status.files[node.absolute_path]
end
explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), status)
if node.nodes and #node.nodes > 0 then
M.reload_node_status(node, projects)
end
Expand All @@ -50,7 +47,7 @@ function M.reload_explorer(_, unloaded_bufnr)
end

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

return
end
event_running = true
Expand Down
74 changes: 0 additions & 74 deletions lua/nvim-tree/explorer/common.lua

This file was deleted.

8 changes: 4 additions & 4 deletions lua/nvim-tree/explorer/explore.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local utils = require "nvim-tree.utils"
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 filters = require "nvim-tree.explorer.filters"
local live_filter = require "nvim-tree.live-filter"
Expand All @@ -13,7 +13,7 @@ local function get_type_from(type_, cwd)
end

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 filter_status = filters.prepare(git_status)
while true do
Expand All @@ -39,7 +39,7 @@ local function populate_children(handle, cwd, node, git_status)
if child then
table.insert(node.nodes, child)
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
Expand All @@ -64,7 +64,7 @@ function M.explore(node, status)
populate_children(handle, cwd, node, status)

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
node.group_next = child_folder_only
local ns = M.explore(child_folder_only, status)
Expand Down
6 changes: 4 additions & 2 deletions lua/nvim-tree/explorer/filters.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@ local function git(path, git_status)
end

-- 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
if M.config.filter_git_ignored and status == "!!" then
return true
end

-- filter clean
if M.config.filter_git_clean and status == " " then
if M.config.filter_git_clean and not status then
return true
end

Expand Down
10 changes: 5 additions & 5 deletions lua/nvim-tree/explorer/init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local git = require "nvim-tree.git"
local watch = require "nvim-tree.explorer.watch"
local common = require "nvim-tree.explorer.common"
local explorer_node = require "nvim-tree.explorer.node"

local M = {}

Expand All @@ -24,8 +24,8 @@ end

function Explorer:_load(node)
local cwd = node.link_to or node.absolute_path
local git_statuses = git.load_project_status(cwd)
M.explore(node, git_statuses)
local git_status = git.load_project_status(cwd)
M.explore(node, git_status)
end

function Explorer:expand(node)
Expand All @@ -34,7 +34,7 @@ end

function Explorer:destroy()
local function iterate(node)
common.node_destroy(node)
explorer_node.node_destroy(node)
if node.nodes then
for _, child in pairs(node.nodes) do
iterate(child)
Expand All @@ -45,7 +45,7 @@ function Explorer:destroy()
end

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.filters").setup(opts)
require("nvim-tree.explorer.sorters").setup(opts)
Expand Down
133 changes: 133 additions & 0 deletions lua/nvim-tree/explorer/node.lua
Original file line number Diff line number Diff line change
@@ -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
Loading