Skip to content
Open
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
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
15 changes: 15 additions & 0 deletions lua/neogit/buffers/status/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ M.__index = M

local instances = {}

vim.api.nvim_create_autocmd("BufWritePost", {
pattern = "*",
callback = function(args)
if not config.values.status.fast then
return
end

for _, buf in pairs(instances) do
buf:refresh {
update_diffs = { "*:" .. args.file },
}
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