Keep the middle line stable across a context-size change

When {/} change the -U context size with no selection showing, we re-anchor
the re-rendered diff on the top visible line. Anchor on the middle visible
line instead, so the diff appears to pivot around the line you're most
likely looking at rather than around its top edge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Haller 2026-06-16 16:53:58 +02:00
parent 4c6af62424
commit 39556e80f3

View file

@ -322,9 +322,11 @@ func (self *StagingHelper) restoreDiffLinePositionOnRerender(view *gocui.View, c
// otherwise resets the scroll. Call it on the view about to be re-rendered, right
// before triggering the re-render.
//
// The anchor is the selected line if a selection is showing, otherwise the top
// visible line. We'd like to keep the anchor line itself, but it may not survive the
// re-render: a context line vanishes when the context size shrinks. So we collect the
// The anchor is the selected line if a selection is showing, otherwise the line in
// the middle of the visible content (so what stays put is the line you're most likely
// looking at, not the top edge). We'd like to keep the anchor line itself, but it may
// not survive the re-render: a context line vanishes when the context size shrinks. So
// we collect the
// lines around the anchor as fallbacks (nearest first; see nearbyDiffLines) and land
// on the nearest one that survives — the anchor itself when it does, otherwise the
// closest surviving line, which minimises scrolling. Each is put back at the same
@ -340,7 +342,7 @@ func (self *StagingHelper) PreserveDiffPositionOnRerender(view *gocui.View) {
}
showSelection := view.Highlight
anchorViewLine := view.OriginY()
anchorViewLine := view.MiddleVisibleLineIdx()
if showSelection {
anchorViewLine = view.SelectedLineIdx()
}