From de8b19c247a108761d752a94df15ccbcb371069f Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 10 Jun 2026 19:47:32 +0200 Subject: [PATCH] Preserve the diff scroll position when switching pagers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cycling pagers re-renders the diff into the main view. Until now that either lost the scroll position outright — an entry with its own externalDiffCommand changes the actual git command, so the re-render reset the view to the top — or kept it only by raw line number, which a plain pager swap got for free because the git command was unchanged. Raw line number is the wrong anchor: two pagers can structure the same diff very differently (side-by-side vs inline), so the same screen line means something different afterwards. Reuse the identity-based restore (PreserveDiffPositionOnRerender, already driving the -U context-size consumer) to re-anchor on the same patch line instead. That both keeps the position meaningful when the structure changes and covers the externalDiffCommand case the line-number approach couldn't. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/gui/controllers/global_controller.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go index b50ec6d1d..f9e2c13ed 100644 --- a/pkg/gui/controllers/global_controller.go +++ b/pkg/gui/controllers/global_controller.go @@ -190,6 +190,14 @@ func (self *GlobalController) onDiffRenderersChanged() { if currentSide.GetKey() == currentKey || currentKey == context.NORMAL_MAIN_CONTEXT_KEY || currentKey == context.NORMAL_SECONDARY_CONTEXT_KEY { + // Switching pagers re-renders the diff. Keep it anchored on the same patch + // line across the switch, restoring by patch identity rather than raw line + // number: two pagers can structure the same diff very differently (side-by- + // side vs inline), so the same screen line means something different after. + // Without this a plain pager swap keeps the old origin (the git command is + // unchanged) but now pointing at the wrong content, while an entry with its + // own externalDiffCommand changes the git command and so resets to the top. + self.c.Helpers().Staging.PreserveDiffPositionOnRerender(self.c.Contexts().Normal.GetView()) currentSide.HandleRenderToMain() }