perf(git): skip sidebar render when porcelain output unchanged
This commit is contained in:
+45
-4
@@ -37,6 +37,7 @@ local SIDEBAR_WIDTH = 50
|
||||
---@field diff_right_win integer?
|
||||
---@field user_aucmd integer?
|
||||
---@field last_shown_key string?
|
||||
---@field last_render_key string? fingerprint of the last rendered state
|
||||
|
||||
---@type table<integer, ow.Git.StatusState>
|
||||
local state = {}
|
||||
@@ -328,10 +329,41 @@ local function render(bufnr, branch, groups)
|
||||
})
|
||||
end
|
||||
state[bufnr].lines = meta
|
||||
-- The diff windows we last opened may now be showing content for an
|
||||
-- entry whose underlying file has changed. Drop the cache so the next
|
||||
-- show_diff recomputes pre/post panes instead of short-circuiting.
|
||||
state[bufnr].last_shown_key = nil
|
||||
end
|
||||
|
||||
---Build a stable fingerprint of the parsed branch + groups so refresh can
|
||||
---short-circuit when the porcelain state is byte-identical to the last
|
||||
---successful render.
|
||||
---@param branch ow.Git.BranchInfo
|
||||
---@param groups table<string, ow.Git.StatusEntry[]>
|
||||
---@return string
|
||||
local function fingerprint(branch, groups)
|
||||
local parts = {
|
||||
branch.head or "",
|
||||
branch.upstream or "",
|
||||
tostring(branch.ahead),
|
||||
tostring(branch.behind),
|
||||
}
|
||||
for _, section in ipairs(SECTIONS) do
|
||||
local entries = groups[section]
|
||||
if entries then
|
||||
for _, e in ipairs(entries) do
|
||||
table.insert(
|
||||
parts,
|
||||
e.section
|
||||
.. ":"
|
||||
.. (e.path or e.sha or "")
|
||||
.. ":"
|
||||
.. (e.orig or "")
|
||||
.. ":"
|
||||
.. (e.x or "")
|
||||
.. ":"
|
||||
.. (e.y or "")
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
return table.concat(parts, "\0")
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
@@ -356,6 +388,15 @@ local function refresh(bufnr)
|
||||
if not vim.api.nvim_buf_is_valid(bufnr) then
|
||||
return
|
||||
end
|
||||
-- Any fs-event that triggered this refresh might have changed the
|
||||
-- worktree under the diff buffers we last opened; invalidate the
|
||||
-- cache so the next show_diff recomputes panes.
|
||||
s.last_shown_key = nil
|
||||
local fp = fingerprint(branch, groups)
|
||||
if fp == s.last_render_key then
|
||||
return
|
||||
end
|
||||
s.last_render_key = fp
|
||||
render(bufnr, branch, groups)
|
||||
if not saved_path and not saved_sha then
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user