Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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 lua/neogit/buffers/status/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ M.v_discard = function(self)
end
end

self:dispatch_refresh({ update_diff = invalidated_diffs }, "v_discard")
self:dispatch_refresh({ update_diffs = invalidated_diffs }, "v_discard")
Copy link
Member

Choose a reason for hiding this comment

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

😅 I'm just going to push this fix to master.

end
end)
end
Expand Down
13 changes: 13 additions & 0 deletions lua/neogit/buffers/status/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ M.__index = M

local instances = {}

if config.values.status.fast then
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = "*",
callback = function(args)
for _, buf in pairs(instances) do
buf:refresh {
update_diffs = { "*:" .. args.file },
}
end
end,
})
end

---@param instance StatusBuffer
---@param dir string
function M.register(instance, dir)
Expand Down
1 change: 1 addition & 0 deletions lua/neogit/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ end
---@field HEAD_folded? boolean Whether or not this section should be open or closed by default
---@field mode_text? { [string]: string } The text to display for each mode
---@field show_head_commit_hash? boolean Show the commit hash for HEADs in the status buffer
---@field fast? boolean Performs in large repositories, but only identifies file renames after manual refresh

---@class NeogitConfigMappings Consult the config file or documentation for values
---@field finder? { [string]: NeogitConfigMappingsFinder } A dictionary that uses finder commands to set multiple keybinds
Expand Down
28 changes: 24 additions & 4 deletions lua/neogit/lib/git/repository.lua
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,18 @@ function Repo:git_path(...)
return Path:new(self.git_dir):joinpath(...)
end

---@param name string
function Repo:task_with_log(name, state, filter)
local start = vim.uv.now()
self.lib[name](state, filter)
logger.debug(("[REPO]: Refreshed %s in %d ms"):format(name, vim.uv.now() - start))
end

function Repo:tasks(filter, state)
local tasks = {}
for name, fn in pairs(self.lib) do
table.insert(tasks, function()
local start = vim.uv.now()
fn(state, filter)
logger.debug(("[REPO]: Refreshed %s in %d ms"):format(name, vim.uv.now() - start))
self:task_with_log(name, state, filter)
end)
end

Expand Down Expand Up @@ -293,6 +298,15 @@ function Repo:set_state(id)
self.state = self:current_state(id)
end

local function count_entries(table)
local count = 0
for _, _ in pairs(table) do
count = count + 1
end

return count
end

function Repo:refresh(opts)
if self.worktree_root == "" then
logger.debug("[REPO] No git root found - skipping refresh")
Expand Down Expand Up @@ -337,7 +351,13 @@ function Repo:refresh(opts)
self:run_callbacks(start)
end)

a.util.run_all(self:tasks(filter, self:current_state(start)), on_complete)
local state = self:current_state(start)
if opts.partial and count_entries(opts.partial) == 1 and opts.partial.update_diffs then
self:task_with_log("update_status", state, filter)
on_complete()
else
a.util.run_all(self:tasks(filter, state), on_complete)
end
end

Repo.dispatch_refresh = a.void(function(self, opts)
Expand Down
33 changes: 29 additions & 4 deletions lua/neogit/lib/git/status.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local git = require("neogit.lib.git")
local util = require("neogit.lib.util")
local Collection = require("neogit.lib.collection")
local logger = require("neogit.logger")
local config = require("neogit.config")

---@class StatusItem
---@field mode string
Expand Down Expand Up @@ -94,11 +95,35 @@ local function update_status(state, filter)
untracked_files = item_collection(state, "untracked", filter),
}

state.staged.items = {}
state.untracked.items = {}
state.unstaged.items = {}
---@param items StatusItem[]
---@param predicate fun(item: StatusItem):boolean
local function remove_first_matching(items, predicate)
for i, v in ipairs(items) do
if predicate(v) then
table.remove(items, i)
return
end
end
end

local result = git.cli.status.null_separated.porcelain(2).call { hidden = true, remove_ansi = false }
local status_cmd = git.cli.status.null_separated.porcelain(2)
local file = filter[1].file
if config.values.status.fast and file ~= "*" then
status_cmd.args(file)
---@param item StatusItem
---@return boolean
local function is_changed_file(item)
return item.name == file or item.original_name == file
end
remove_first_matching(state.staged.items, is_changed_file)
remove_first_matching(state.unstaged.items, is_changed_file)
remove_first_matching(state.untracked.items, is_changed_file)
else
state.staged.items = {}
state.untracked.items = {}
state.unstaged.items = {}
end
local result = status_cmd.call { hidden = true, remove_ansi = false }
result = vim.split(result.stdout[1] or "", "\n")
result = util.collect(result, function(line, collection)
if line == "" then
Expand Down
Loading