fix(init): skip carry-forward when hunk count changes

Problem: when fugitive collapses a diff section, Neovim repositions
extmarks from deleted lines onto surviving lines. `carry_forward_highlighted`
matched hunks by content only, carrying forward the "highlighted" flag
for stable hunks and leaving stale extmarks from removed hunks uncleaned.

Solution: add `#entry.hunks == #hunks` guard to the carry-forward
precondition. When hunk count changes, skip carry-forward and set
`pending_clear = true` so `on_buf` wipes all extmarks before
`on_win` re-highlights visible hunks.
This commit is contained in:
Barrett Ruth 2026-03-15 12:35:37 -04:00
parent 803e08b6d5
commit aeb74e0616
Signed by: barrett
GPG key ID: A6C96C9349D2FC81

View file

@ -165,7 +165,7 @@ describe('decoration_provider', function()
end)
describe('hunk stability', function()
it('carries forward highlighted for stable hunks on section expansion', function()
it('forces full clear on section expansion (hunk count changed)', function()
local bufnr = create_buffer({
'M test.lua',
'@@ -1,2 +1,2 @@',
@ -193,14 +193,12 @@ describe('decoration_provider', function()
local updated = diffs._test.hunk_cache[bufnr]
assert.are.equal(3, #updated.hunks)
assert.is_true(updated.highlighted[1] == true)
assert.is_nil(updated.highlighted[2])
assert.is_true(updated.highlighted[3] == true)
assert.is_false(updated.pending_clear)
assert.are.same({}, updated.highlighted)
assert.is_true(updated.pending_clear)
delete_buffer(bufnr)
end)
it('carries forward highlighted for stable hunks on section collapse', function()
it('forces full clear on section collapse (stale extmarks from removed hunks)', function()
local bufnr = create_buffer({
'M test.lua',
'@@ -1,2 +1,2 @@',
@ -227,9 +225,8 @@ describe('decoration_provider', function()
local updated = diffs._test.hunk_cache[bufnr]
assert.are.equal(2, #updated.hunks)
assert.is_true(updated.highlighted[1] == true)
assert.is_true(updated.highlighted[2] == true)
assert.is_false(updated.pending_clear)
assert.are.same({}, updated.highlighted)
assert.is_true(updated.pending_clear)
delete_buffer(bufnr)
end)