Skip to content

fix(#2382): correct submodule and worktree .git watchers, refactor lazy git projects #2390

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

Closed
Closed
28 changes: 16 additions & 12 deletions lua/nvim-tree/actions/reloaders/reloaders.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ local Iterator = require "nvim-tree.iterators.node-iterator"

local M = {}

local function refresh_nodes(node, projects, unloaded_bufnr)
local function refresh_nodes(node, unloaded_bufnr)
Iterator.builder({ node })
:applier(function(n)
if n.open and n.nodes then
local project_root = git.get_project_root(n.cwd or n.link_to or n.absolute_path)
explorer_module.reload(n, projects[project_root] or {}, unloaded_bufnr)
local project = git.get_project(n.cwd or n.link_to or n.absolute_path)
if project then
explorer_module.reload(n, project, unloaded_bufnr)
end
end
end)
:recursor(function(n)
Expand All @@ -22,13 +24,15 @@ local function refresh_nodes(node, projects, unloaded_bufnr)
:iterate()
end

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 {}
function M.reload_node_status(parent_node)
local project = git.get_project(parent_node.absolute_path)
if not project then
return
end
for _, node in ipairs(parent_node.nodes) do
explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), status)
explorer_node.update_git_status(node, explorer_node.is_git_ignored(parent_node), project)
if node.nodes and #node.nodes > 0 then
M.reload_node_status(node, projects)
M.reload_node_status(node)
end
end
end
Expand All @@ -42,8 +46,8 @@ function M.reload_explorer(_, unloaded_bufnr)
end
event_running = true

local projects = git.reload()
refresh_nodes(core.get_explorer(), projects, unloaded_bufnr)
git.reload()
refresh_nodes(core.get_explorer(), unloaded_bufnr)
if view.is_visible() then
renderer.draw(unloaded_bufnr)
end
Expand All @@ -56,8 +60,8 @@ function M.reload_git()
end
event_running = true

local projects = git.reload()
M.reload_node_status(core.get_explorer(), projects)
git.reload()
M.reload_node_status(core.get_explorer())
renderer.draw()
event_running = false
end
Expand Down
8 changes: 4 additions & 4 deletions lua/nvim-tree/explorer/explore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ local function populate_children(handle, cwd, node, git_status)
end
end

function M.explore(node, status)
function M.explore(node, project)
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
Expand All @@ -66,15 +66,15 @@ function M.explore(node, status)

local profile = log.profile_start("explore init %s", node.absolute_path)

populate_children(handle, cwd, node, status)
populate_children(handle, cwd, node, project)

local is_root = not node.parent
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
local child_cwd = child_folder_only.link_to or child_folder_only.absolute_path
local child_status = git.load_project_status(child_cwd)
local child_project = git.get_project(child_cwd)
node.group_next = child_folder_only
local ns = M.explore(child_folder_only, child_status)
local ns = M.explore(child_folder_only, child_project)
node.nodes = ns or {}

log.profile_end(profile)
Expand Down
4 changes: 2 additions & 2 deletions lua/nvim-tree/explorer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ end

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

function Explorer:expand(node)
Expand Down
10 changes: 7 additions & 3 deletions lua/nvim-tree/explorer/node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ 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)
function M.update_git_status(node, parent_ignored, project)
if not project then
return
end

local get_status
if node.nodes then
get_status = get_dir_git_status
Expand All @@ -41,11 +45,11 @@ function M.update_git_status(node, parent_ignored, status)
end

-- status of the node's absolute path
node.git_status = get_status(parent_ignored, status, node.absolute_path)
node.git_status = get_status(parent_ignored, project, 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)
node.git_status = get_status(parent_ignored, project, node.link_to)
end
end

Expand Down
31 changes: 11 additions & 20 deletions lua/nvim-tree/explorer/reload.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,24 @@ local function update_status(nodes_by_path, node_ignored, status)
end
end

local function reload_and_get_git_project(path, callback)
local project_root = git.get_project_root(path)

git.reload_project(project_root, path, function()
callback(project_root, git.get_project(project_root) or {})
end)
end

local function update_parent_statuses(node, project, root)
local function update_parent_statuses(node, project)
while project and node do
-- step up to the containing project
if node.absolute_path == root then
if node.absolute_path == project.toplevel then
-- stop at the top of the tree
if not node.parent then
break
end

root = git.get_project_root(node.parent.absolute_path)
project = git.get_project(node.parent.absolute_path)

-- stop when no more projects
if not root then
if not project then
break
end

-- update the containing project
project = git.get_project(root)
git.reload_project(root, node.absolute_path, nil)
git.reload_project(project, node.absolute_path, nil)
end

-- update status
Expand Down Expand Up @@ -172,12 +163,13 @@ function M.refresh_node(node, callback)
callback()
end

local project = git.get_project(node.absolute_path)
local parent_node = utils.get_parent_of_group(node)

reload_and_get_git_project(node.absolute_path, function(project_root, project)
require("nvim-tree.explorer.reload").reload(parent_node, project)
git.reload_project(project, node.absolute_path, function()
M.reload(parent_node, project)

update_parent_statuses(parent_node, project, project_root)
update_parent_statuses(parent_node, project)

callback()
end)
Expand Down Expand Up @@ -211,11 +203,10 @@ function M.refresh_parent_nodes_for_path(path)

-- refresh in order; this will expand groups as needed
for _, node in ipairs(parent_nodes) do
local project_root = git.get_project_root(node.absolute_path)
local project = git.get_project(project_root) or {}
local project = git.get_project(node.absolute_path)

M.reload(node, project)
update_parent_statuses(node, project, project_root)
update_parent_statuses(node, project)
end

log.profile_end(profile)
Expand Down
Loading