Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
227 changes: 117 additions & 110 deletions lua/neo-tree/git/status.lua
Original file line number Diff line number Diff line change
Expand Up @@ -201,129 +201,136 @@ local function parse_lines_batch(context, job_complete_callback)
end

M.status_async = function(path, base, opts)
local git_root = git_utils.get_repository_root(path)
if utils.truthy(git_root) then
log.trace("git.status.status_async called")
else
log.trace("status_async: not a git folder: ", path)
return false
end
git_utils.get_repository_root(path, function(git_root)
if utils.truthy(git_root) then
log.trace("git.status.status_async called")
else
log.trace("status_async: not a git folder: ", path)
return false
end

local event_id = "git_status_" .. git_root
local context = {
git_root = git_root,
git_status = {},
exclude_directories = false,
lines = {},
lines_parsed = 0,
batch_size = opts.batch_size or 1000,
batch_delay = opts.batch_delay or 10,
max_lines = opts.max_lines or 100000,
}
local event_id = "git_status_" .. git_root
local context = {
git_root = git_root,
git_status = {},
exclude_directories = false,
lines = {},
lines_parsed = 0,
batch_size = opts.batch_size or 1000,
batch_delay = opts.batch_delay or 10,
max_lines = opts.max_lines or 100000,
}

local should_process = function(err, line, job, err_msg)
if vim.v.dying > 0 or vim.v.exiting ~= vim.NIL then
job:shutdown()
return false
local should_process = function(err, line, job, err_msg)
if vim.v.dying > 0 or vim.v.exiting ~= vim.NIL then
job:shutdown()
return false
end
if err and err > 0 then
log.error(err_msg, err, line)
return false
end
return true
end
if err and err > 0 then
log.error(err_msg, err, line)
return false

local job_complete_callback = function()
utils.debounce(event_id, nil, nil, nil, utils.debounce_action.COMPLETE_ASYNC_JOB)
vim.schedule(function()
events.fire_event(events.GIT_STATUS_CHANGED, {
git_root = context.git_root,
git_status = context.git_status,
})
end)
end
return true
end

local job_complete_callback = function()
utils.debounce(event_id, nil, nil, nil, utils.debounce_action.COMPLETE_ASYNC_JOB)
vim.schedule(function()
events.fire_event(events.GIT_STATUS_CHANGED, {
git_root = context.git_root,
git_status = context.git_status,
})
local parse_lines = vim.schedule_wrap(function()
parse_lines_batch(context, job_complete_callback)
end)
end

local parse_lines = vim.schedule_wrap(function()
parse_lines_batch(context, job_complete_callback)
end)

utils.debounce(event_id, function()
local staged_job = Job:new({
command = "git",
args = { "-C", git_root, "diff", "--staged", "--name-status", base, "--" },
enable_recording = false,
maximium_results = context.max_lines,
on_stdout = vim.schedule_wrap(function(err, line, job)
if should_process(err, line, job, "status_async staged error:") then
table.insert(context.lines, line)
end
end),
on_stderr = function(err, line)
if err and err > 0 then
log.error("status_async staged error: ", err, line)
end
end,
})
utils.debounce(event_id, function()
local staged_job = Job:new({
command = "git",
args = { "-C", git_root, "diff", "--staged", "--name-status", base, "--" },
enable_recording = false,
maximium_results = context.max_lines,
on_stdout = vim.schedule_wrap(function(err, line, job)
if should_process(err, line, job, "status_async staged error:") then
table.insert(context.lines, line)
end
end),
on_stderr = function(err, line)
if err and err > 0 then
log.error("status_async staged error: ", err, line)
end
end,
})

local unstaged_job = Job:new({
command = "git",
args = { "-C", git_root, "diff", "--name-status" },
enable_recording = false,
maximium_results = context.max_lines,
on_stdout = vim.schedule_wrap(function(err, line, job)
if should_process(err, line, job, "status_async unstaged error:") then
if line then
line = " " .. line
local unstaged_job = Job:new({
command = "git",
args = { "-C", git_root, "diff", "--name-status" },
enable_recording = false,
maximium_results = context.max_lines,
on_stdout = vim.schedule_wrap(function(err, line, job)
if should_process(err, line, job, "status_async unstaged error:") then
if line then
line = " " .. line
end
table.insert(context.lines, line)
end
end),
on_stderr = function(err, line)
if err and err > 0 then
log.error("status_async unstaged error: ", err, line)
end
table.insert(context.lines, line)
end
end),
on_stderr = function(err, line)
if err and err > 0 then
log.error("status_async unstaged error: ", err, line)
end
end,
})
end,
})

local untracked_job = Job:new({
command = "git",
args = { "-C", git_root, "ls-files", "--exclude-standard", "--others" },
enable_recording = false,
maximium_results = context.max_lines,
on_stdout = vim.schedule_wrap(function(err, line, job)
if should_process(err, line, job, "status_async untracked error:") then
if line then
line = "? " .. line
local untracked_job = Job:new({
command = "git",
args = { "-C", git_root, "ls-files", "--exclude-standard", "--others" },
enable_recording = false,
maximium_results = context.max_lines,
on_stdout = vim.schedule_wrap(function(err, line, job)
if should_process(err, line, job, "status_async untracked error:") then
if line then
line = "? " .. line
end
table.insert(context.lines, line)
end
end),
on_stderr = function(err, line)
if err and err > 0 then
log.error("status_async untracked error: ", err, line)
end
table.insert(context.lines, line)
end
end),
on_stderr = function(err, line)
if err and err > 0 then
log.error("status_async untracked error: ", err, line)
end
end,
})
end,
})

local showUntracked = vim.fn.systemlist({
"git",
"-C",
git_root,
"config",
"--get",
"status.showUntrackedFiles",
})
log.debug("git status.showUntrackedFiles =", showUntracked[1])
if showUntracked[1] == "no" then
unstaged_job:after(parse_lines)
Job.chain(staged_job, unstaged_job)
else
untracked_job:after(parse_lines)
Job.chain(staged_job, unstaged_job, untracked_job)
end
end, 1000, utils.debounce_strategy.CALL_FIRST_AND_LAST, utils.debounce_action.START_ASYNC_JOB)
Job:new({
command = "git",
args = {
"-C",
git_root,
"config",
"--get",
"status.showUntrackedFiles",
},
enabled_recording = true,
on_exit = function(self, _, _)
local result = self:result()
log.debug("git status.showUntrackedFiles =", result[1])
if result[1] == "no" then
unstaged_job:after(parse_lines)
Job.chain(staged_job, unstaged_job)
else
untracked_job:after(parse_lines)
Job.chain(staged_job, unstaged_job, untracked_job)
end
end,
}):start()
end, 1000, utils.debounce_strategy.CALL_FIRST_AND_LAST, utils.debounce_action.START_ASYNC_JOB)

return true
return true
end)
end

return M
53 changes: 39 additions & 14 deletions lua/neo-tree/git/utils.lua
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
local Job = require("plenary.job")

local utils = require("neo-tree.utils")
local log = require("neo-tree.log")

local M = {}

M.get_repository_root = function(path)
local cmd = { "git", "rev-parse", "--show-toplevel" }
M.get_repository_root = function(path, callback)
local args = { "rev-parse", "--show-toplevel" }
if utils.truthy(path) then
cmd = { "git", "-C", path, "rev-parse", "--show-toplevel" }
end
local ok, git_root = utils.execute_command(cmd)
if not ok then
log.trace("GIT ROOT ERROR ", git_root)
return nil
args = { "-C", path, "rev-parse", "--show-toplevel" }
end
git_root = git_root[1]
if type(callback) == "function" then
Job:new({
command = "git",
args = args,
enabled_recording = true,
on_exit = function(self, code, _)
if code ~= 0 then
log.trace("GIT ROOT ERROR ", self:stderr_result())
callback(nil)
return
end
local git_root = self:result()[1]

if utils.is_windows then
git_root = utils.windowize_path(git_root)
end
if utils.is_windows then
git_root = utils.windowize_path(git_root)
end

log.trace("GIT ROOT for '", path, "' is '", git_root, "'")
return git_root
log.trace("GIT ROOT for '", path, "' is '", git_root, "'")
callback(git_root)
end,
}):start()
else
local ok, git_root = utils.execute_command({ "git", unpack(args) })
if not ok then
log.trace("GIT ROOT ERROR ", git_root)
return nil
end
git_root = git_root[1]

if utils.is_windows then
git_root = utils.windowize_path(git_root)
end

log.trace("GIT ROOT for '", path, "' is '", git_root, "'")
return git_root
end
end

return M
7 changes: 2 additions & 5 deletions lua/neo-tree/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,8 @@ end
log.new = function(config, standalone)
config = vim.tbl_deep_extend("force", default_config, config)

local outfile = string.format(
"%s/%s.log",
vim.api.nvim_call_function("stdpath", { "data" }),
config.plugin
)
local outfile =
string.format("%s/%s.log", vim.api.nvim_call_function("stdpath", { "data" }), config.plugin)

local obj
if standalone then
Expand Down
15 changes: 4 additions & 11 deletions lua/neo-tree/setup/deprecations.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ M.migrate = function(config)
end
utils.set_value(config, new, exising)
config[old] = nil
migrations[#migrations + 1] = string.format(
"The `%s` option has been deprecated, please use `%s` instead.",
old,
new
)
migrations[#migrations + 1] =
string.format("The `%s` option has been deprecated, please use `%s` instead.", old, new)
end
end

Expand All @@ -61,12 +58,8 @@ M.migrate = function(config)
local value = utils.get_value(config, key)
if value == old_value then
utils.set_value(config, key, new_value)
migrations[#migrations + 1] = string.format(
"The `%s=%s` option has been renamed to `%s`.",
key,
old_value,
new_value
)
migrations[#migrations + 1] =
string.format("The `%s=%s` option has been renamed to `%s`.", key, old_value, new_value)
end
end

Expand Down
Loading