From 646b080a384e2f6e8fe435fb7182075b7543b74c Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 4 Dec 2025 17:45:24 +0800 Subject: [PATCH] feature: remember last navigated block after toggling `Show All Lines` (#1952) Signed-off-by: leo --- src/ViewModels/BlockNavigation.cs | 14 +++++++++---- src/ViewModels/DiffContext.cs | 7 +++---- src/ViewModels/TextDiffContext.cs | 34 +++++++++++++++---------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/ViewModels/BlockNavigation.cs b/src/ViewModels/BlockNavigation.cs index f8274553..96f47146 100644 --- a/src/ViewModels/BlockNavigation.cs +++ b/src/ViewModels/BlockNavigation.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using CommunityToolkit.Mvvm.ComponentModel; @@ -35,13 +36,15 @@ namespace SourceGit.ViewModels } } - public BlockNavigation(List lines, bool gotoFirst) + public BlockNavigation(List lines, int cur) { _blocks.Clear(); - _current = -1; if (lines.Count == 0) + { + _current = -1; return; + } var lineIdx = 0; var blockStartIdx = 0; @@ -73,9 +76,12 @@ namespace SourceGit.ViewModels blocks.Add(new Block(blockStartIdx, lines.Count)); _blocks.AddRange(blocks); + _current = Math.Min(_blocks.Count - 1, cur); + } - if (gotoFirst) - Goto(BlockNavigationDirection.First); + public int GetCurrentBlockIndex() + { + return _current; } public Block GetCurrentBlock() diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index 8bc7f804..6db7ba22 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -150,8 +150,7 @@ namespace SourceGit.ViewModels Task.Run(async () => { - var showEntireFile = Preferences.Instance.UseFullTextDiff; - var numLines = showEntireFile ? _entireFileLine : _unifiedLines; + var numLines = Preferences.Instance.UseFullTextDiff ? _entireFileLine : _unifiedLines; var ignoreWhitespace = Preferences.Instance.IgnoreWhitespaceChangesInDiff; var latest = await new Commands.Diff(_repo, _option, numLines, ignoreWhitespace) @@ -274,9 +273,9 @@ namespace SourceGit.ViewModels IsTextDiff = true; if (Preferences.Instance.UseSideBySideDiff) - Content = new TwoSideTextDiff(_option, showEntireFile, cur, _content as TwoSideTextDiff); + Content = new TwoSideTextDiff(_option, cur, _content as TwoSideTextDiff); else - Content = new CombinedTextDiff(_option, showEntireFile, cur, _content as CombinedTextDiff); + Content = new CombinedTextDiff(_option, cur, _content as CombinedTextDiff); } else { diff --git a/src/ViewModels/TextDiffContext.cs b/src/ViewModels/TextDiffContext.cs index 160da07f..6771fa9b 100644 --- a/src/ViewModels/TextDiffContext.cs +++ b/src/ViewModels/TextDiffContext.cs @@ -130,30 +130,33 @@ namespace SourceGit.ViewModels return null; } - protected bool TryKeepPrevScrollOffset(TextDiffContext prev) + protected void TryKeepPrevState(TextDiffContext prev, List lines) { var fastTest = prev != null && - prev._showEntireFile == _showEntireFile && prev._option.IsUnstaged == _option.IsUnstaged && prev._option.Path.Equals(_option.Path, StringComparison.Ordinal) && prev._option.OrgPath.Equals(_option.OrgPath, StringComparison.Ordinal) && prev._option.Revisions.Count == _option.Revisions.Count; if (!fastTest) - return false; + { + _blockNavigation = new BlockNavigation(lines, 0); + return; + } for (int i = 0; i < _option.Revisions.Count; i++) { if (!prev._option.Revisions[i].Equals(_option.Revisions[i], StringComparison.Ordinal)) - return false; + { + _blockNavigation = new BlockNavigation(lines, 0); + return; + } } - _scrollOffset = prev._scrollOffset; - return true; + _blockNavigation = new BlockNavigation(lines, prev._blockNavigation.GetCurrentBlockIndex()); } protected Models.DiffOption _option = null; - protected bool _showEntireFile = false; protected Models.TextDiff _data = null; protected Vector _scrollOffset = Vector.Zero; protected BlockNavigation _blockNavigation = null; @@ -164,19 +167,17 @@ namespace SourceGit.ViewModels public class CombinedTextDiff : TextDiffContext { - public CombinedTextDiff(Models.DiffOption option, bool showEntireFile, Models.TextDiff diff, CombinedTextDiff previous = null) + public CombinedTextDiff(Models.DiffOption option, Models.TextDiff diff, CombinedTextDiff previous = null) { _option = option; - _showEntireFile = showEntireFile; _data = diff; - var keep = TryKeepPrevScrollOffset(previous); - _blockNavigation = new BlockNavigation(_data.Lines, !keep); + TryKeepPrevState(previous, _data.Lines); } public override TextDiffContext SwitchMode() { - return new TwoSideTextDiff(_option, _showEntireFile, _data); + return new TwoSideTextDiff(_option, _data); } } @@ -185,10 +186,9 @@ namespace SourceGit.ViewModels public List Old { get; } = []; public List New { get; } = []; - public TwoSideTextDiff(Models.DiffOption option, bool showEntireFile, Models.TextDiff diff, TwoSideTextDiff previous = null) + public TwoSideTextDiff(Models.DiffOption option, Models.TextDiff diff, TwoSideTextDiff previous = null) { _option = option; - _showEntireFile = showEntireFile; _data = diff; foreach (var line in diff.Lines) @@ -210,9 +210,7 @@ namespace SourceGit.ViewModels } FillEmptyLines(); - - var keep = TryKeepPrevScrollOffset(previous); - _blockNavigation = new BlockNavigation(Old, !keep); + TryKeepPrevState(previous, Old); } public override bool IsSideBySide() @@ -222,7 +220,7 @@ namespace SourceGit.ViewModels public override TextDiffContext SwitchMode() { - return new CombinedTextDiff(_option, _showEntireFile, _data); + return new CombinedTextDiff(_option, _data); } public void ConvertsToCombinedRange(ref int startLine, ref int endLine, bool isOldSide)