feat/chore: rewrite git with job and some other fixes (#743)
* feat/chore: rewrite git with job and some other fixes * fix: fs clear window, rename echo_warning -> warn also fix renaming and add an event blocker to avoid running many events at the same time
This commit is contained in:
@@ -3,12 +3,12 @@ local luv = vim.loop
|
||||
|
||||
local renderer = require'nvim-tree.renderer'
|
||||
local config = require'nvim-tree.config'
|
||||
local git = require'nvim-tree.git'
|
||||
local diagnostics = require'nvim-tree.diagnostics'
|
||||
local pops = require'nvim-tree.populate'
|
||||
local utils = require'nvim-tree.utils'
|
||||
local view = require'nvim-tree.view'
|
||||
local events = require'nvim-tree.events'
|
||||
local git = require'nvim-tree.git'
|
||||
local populate = pops.populate
|
||||
local refresh_entries = pops.refresh_entries
|
||||
|
||||
@@ -19,33 +19,25 @@ local M = {}
|
||||
M.Tree = {
|
||||
entries = {},
|
||||
cwd = nil,
|
||||
loaded = false,
|
||||
target_winid = nil,
|
||||
}
|
||||
|
||||
function M.init(with_open, with_reload)
|
||||
M.Tree.entries = {}
|
||||
if not M.Tree.cwd then
|
||||
M.Tree.cwd = luv.cwd()
|
||||
end
|
||||
if config.use_git() then
|
||||
git.git_root(M.Tree.cwd)
|
||||
end
|
||||
populate(M.Tree.entries, M.Tree.cwd)
|
||||
local function load_children(cwd, children, parent)
|
||||
git.load_project_status(cwd, function(git_statuses)
|
||||
populate(children, cwd, parent, git_statuses)
|
||||
M.redraw()
|
||||
end)
|
||||
end
|
||||
|
||||
local stat = luv.fs_stat(M.Tree.cwd)
|
||||
M.Tree.last_modified = stat.mtime.sec
|
||||
function M.init(with_open, foldername)
|
||||
M.Tree.entries = {}
|
||||
M.Tree.cwd = foldername or luv.cwd()
|
||||
|
||||
if with_open then
|
||||
M.open()
|
||||
elseif view.win_open() then
|
||||
M.refresh_tree()
|
||||
end
|
||||
|
||||
if with_reload then
|
||||
renderer.draw(M.Tree, true)
|
||||
M.Tree.loaded = true
|
||||
end
|
||||
load_children(M.Tree.cwd, M.Tree.entries)
|
||||
|
||||
if not first_init_done then
|
||||
events._dispatch_ready()
|
||||
@@ -85,7 +77,7 @@ local function get_line_from_node(node, find_parent)
|
||||
local function iter(entries, recursive)
|
||||
for _, entry in ipairs(entries) do
|
||||
local n = M.get_last_group_node(entry)
|
||||
if node_path:match('^'..n.match_path..'$') ~= nil then
|
||||
if node_path == n.absolute_path then
|
||||
return line, entry
|
||||
end
|
||||
|
||||
@@ -132,73 +124,75 @@ function M.get_last_group_node(node)
|
||||
return next
|
||||
end
|
||||
|
||||
function M.unroll_dir(node)
|
||||
function M.expand_or_collapse(node)
|
||||
node.open = not node.open
|
||||
if node.has_children then node.has_children = false end
|
||||
if #node.entries > 0 then
|
||||
renderer.draw(M.Tree, true)
|
||||
if #node.entries == 0 then
|
||||
load_children(
|
||||
node.link_to or node.absolute_path,
|
||||
node.entries,
|
||||
node
|
||||
)
|
||||
else
|
||||
if config.use_git() then
|
||||
git.git_root(node.absolute_path)
|
||||
end
|
||||
populate(node.entries, node.link_to or node.absolute_path, node)
|
||||
|
||||
renderer.draw(M.Tree, true)
|
||||
M.redraw()
|
||||
end
|
||||
|
||||
diagnostics.update()
|
||||
end
|
||||
|
||||
local function refresh_git(node)
|
||||
if not node then node = M.Tree end
|
||||
git.update_status(node.entries, node.absolute_path or node.cwd, node, false)
|
||||
for _, entry in pairs(node.entries) do
|
||||
if entry.entries and #entry.entries > 0 then
|
||||
refresh_git(entry)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO update only entries where directory has changed
|
||||
local function refresh_nodes(node)
|
||||
refresh_entries(node.entries, node.absolute_path or node.cwd, node)
|
||||
local function refresh_nodes(node, projects)
|
||||
local project_root = git.get_project_root(node.absolute_path or node.cwd)
|
||||
refresh_entries(node.entries, node.absolute_path or node.cwd, node, projects[project_root] or {})
|
||||
for _, entry in ipairs(node.entries) do
|
||||
if entry.entries and entry.open then
|
||||
refresh_nodes(entry)
|
||||
refresh_nodes(entry, projects)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- this variable is used to bufferize the refresh actions
|
||||
-- so only one happens every second at most
|
||||
local refreshing = false
|
||||
|
||||
function M.refresh_tree(disable_clock)
|
||||
if not M.Tree.cwd or (not disable_clock and refreshing) or vim.v.exiting ~= vim.NIL then
|
||||
local event_running = false
|
||||
function M.refresh_tree()
|
||||
if event_running or not M.Tree.cwd or vim.v.exiting ~= vim.NIL then
|
||||
return
|
||||
end
|
||||
refreshing = true
|
||||
event_running = true
|
||||
|
||||
refresh_nodes(M.Tree)
|
||||
|
||||
local use_git = config.use_git()
|
||||
if use_git then
|
||||
vim.schedule(function()
|
||||
git.reload_roots()
|
||||
refresh_git(M.Tree)
|
||||
git.reload(function(projects)
|
||||
refresh_nodes(M.Tree, projects)
|
||||
if view.win_open() then
|
||||
M.redraw()
|
||||
end)
|
||||
end
|
||||
diagnostics.update()
|
||||
event_running = false
|
||||
end)
|
||||
end
|
||||
|
||||
local function reload_node_status(parent_node, projects)
|
||||
local project_root = git.get_project_root(parent_node.absolute_path or parent_node.cwd)
|
||||
local status = projects[project_root] or {}
|
||||
for _, node in ipairs(parent_node.entries) do
|
||||
if node.entries 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
|
||||
if node.entries and #node.entries > 0 then
|
||||
reload_node_status(node, projects)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vim.schedule(diagnostics.update)
|
||||
|
||||
if view.win_open() then
|
||||
renderer.draw(M.Tree, true)
|
||||
else
|
||||
M.Tree.loaded = false
|
||||
function M.reload_git()
|
||||
if not git.config.enable or event_running then
|
||||
return
|
||||
end
|
||||
event_running = true
|
||||
|
||||
vim.defer_fn(function() refreshing = false end, vim.g.nvim_tree_refresh_wait or 1000)
|
||||
git.reload(function(projects)
|
||||
reload_node_status(M.Tree, projects)
|
||||
M.redraw()
|
||||
event_running = false
|
||||
end)
|
||||
end
|
||||
|
||||
function M.set_index_and_redraw(fname)
|
||||
@@ -209,40 +203,46 @@ function M.set_index_and_redraw(fname)
|
||||
else
|
||||
i = 1
|
||||
end
|
||||
local reload = false
|
||||
|
||||
local function iter(entries)
|
||||
for _, entry in ipairs(entries) do
|
||||
local tree_altered = false
|
||||
|
||||
local function iterate_nodes(nodes)
|
||||
for _, node in ipairs(nodes) do
|
||||
i = i + 1
|
||||
if entry.absolute_path == fname then
|
||||
if node.absolute_path == fname then
|
||||
return i
|
||||
end
|
||||
|
||||
if fname:match(entry.match_path..utils.path_separator) ~= nil then
|
||||
if #entry.entries == 0 then
|
||||
reload = true
|
||||
populate(entry.entries, entry.absolute_path, entry)
|
||||
local path_matches = utils.str_find(fname, node.absolute_path..utils.path_separator)
|
||||
if path_matches then
|
||||
if #node.entries == 0 then
|
||||
node.open = true
|
||||
populate(node.entries, node.absolute_path, node, {})
|
||||
git.load_project_status(node.absolute_path, function(status)
|
||||
if status.dirs or status.files then
|
||||
reload_node_status(node, git.projects)
|
||||
M.redraw()
|
||||
end
|
||||
end)
|
||||
end
|
||||
if entry.open == false then
|
||||
reload = true
|
||||
entry.open = true
|
||||
if node.open == false then
|
||||
node.open = true
|
||||
tree_altered = true
|
||||
end
|
||||
if iter(entry.entries) ~= nil then
|
||||
if iterate_nodes(node.entries) ~= nil then
|
||||
return i
|
||||
end
|
||||
elseif entry.open == true then
|
||||
iter(entry.entries)
|
||||
elseif node.open == true then
|
||||
iterate_nodes(node.entries)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local index = iter(M.Tree.entries)
|
||||
if not view.win_open() then
|
||||
M.Tree.loaded = false
|
||||
return
|
||||
local index = iterate_nodes(M.Tree.entries)
|
||||
if tree_altered then
|
||||
M.redraw()
|
||||
end
|
||||
renderer.draw(M.Tree, reload)
|
||||
if index then
|
||||
if index and view.win_open() then
|
||||
view.set_cursor({index, 0})
|
||||
end
|
||||
end
|
||||
@@ -405,8 +405,6 @@ function M.open_file(mode, filename)
|
||||
if vim.g.nvim_tree_quit_on_open == 1 then
|
||||
view.close()
|
||||
end
|
||||
|
||||
renderer.draw(M.Tree, true)
|
||||
end
|
||||
|
||||
function M.open_file_in_tab(filename)
|
||||
@@ -467,8 +465,7 @@ function M.change_dir(name)
|
||||
end
|
||||
|
||||
vim.cmd('lcd '..vim.fn.fnameescape(foldername))
|
||||
M.Tree.cwd = foldername
|
||||
M.init(false, true)
|
||||
M.init(false, foldername)
|
||||
end
|
||||
|
||||
function M.set_target_win()
|
||||
@@ -486,18 +483,19 @@ function M.open()
|
||||
M.set_target_win()
|
||||
|
||||
local cwd = vim.fn.getcwd()
|
||||
view.open()
|
||||
local should_redraw = view.open()
|
||||
|
||||
local respect_buf_cwd = vim.g.nvim_tree_respect_buf_cwd or 0
|
||||
if M.Tree.loaded and (respect_buf_cwd == 1 and cwd ~= M.Tree.cwd) then
|
||||
if respect_buf_cwd == 1 and cwd ~= M.Tree.cwd then
|
||||
M.change_dir(cwd)
|
||||
end
|
||||
renderer.draw(M.Tree, not M.Tree.loaded)
|
||||
M.Tree.loaded = true
|
||||
if should_redraw then
|
||||
M.redraw()
|
||||
end
|
||||
end
|
||||
|
||||
function M.sibling(node, direction)
|
||||
if not direction then return end
|
||||
if node.name == '..' or not direction then return end
|
||||
|
||||
local iter = get_line_from_node(node, true)
|
||||
local node_path = node.absolute_path
|
||||
@@ -507,7 +505,7 @@ function M.sibling(node, direction)
|
||||
|
||||
-- Check if current node is already at root entries
|
||||
for index, entry in ipairs(M.Tree.entries) do
|
||||
if node_path:match('^'..entry.match_path..'$') ~= nil then
|
||||
if node_path == entry.absolute_path then
|
||||
line = index
|
||||
end
|
||||
end
|
||||
@@ -534,7 +532,6 @@ function M.sibling(node, direction)
|
||||
|
||||
line, _ = get_line_from_node(target_node)(M.Tree.entries, true)
|
||||
view.set_cursor({line, 0})
|
||||
renderer.draw(M.Tree, true)
|
||||
end
|
||||
|
||||
function M.close_node(node)
|
||||
@@ -543,11 +540,14 @@ end
|
||||
|
||||
function M.parent_node(node, should_close)
|
||||
if node.name == '..' then return end
|
||||
|
||||
should_close = should_close or false
|
||||
local altered_tree = false
|
||||
|
||||
local iter = get_line_from_node(node, true)
|
||||
if node.open == true and should_close then
|
||||
node.open = false
|
||||
altered_tree = true
|
||||
else
|
||||
local line, parent = iter(M.Tree.entries, true)
|
||||
if parent == nil then
|
||||
@@ -555,9 +555,12 @@ function M.parent_node(node, should_close)
|
||||
elseif should_close then
|
||||
parent.open = false
|
||||
end
|
||||
api.nvim_win_set_cursor(view.get_winnr(), {line, 0})
|
||||
view.set_cursor({line, 0})
|
||||
end
|
||||
|
||||
if altered_tree then
|
||||
M.redraw()
|
||||
end
|
||||
renderer.draw(M.Tree, true)
|
||||
end
|
||||
|
||||
function M.toggle_ignored()
|
||||
|
||||
Reference in New Issue
Block a user