feature: remember last navigated block after toggling Show All Lines (#1952)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo
2025-12-04 17:45:24 +08:00
parent 291361df5c
commit 646b080a38
3 changed files with 29 additions and 26 deletions

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using CommunityToolkit.Mvvm.ComponentModel;
@@ -35,13 +36,15 @@ namespace SourceGit.ViewModels
}
}
public BlockNavigation(List<Models.TextDiffLine> lines, bool gotoFirst)
public BlockNavigation(List<Models.TextDiffLine> 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()

View File

@@ -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
{

View File

@@ -130,30 +130,33 @@ namespace SourceGit.ViewModels
return null;
}
protected bool TryKeepPrevScrollOffset(TextDiffContext prev)
protected void TryKeepPrevState(TextDiffContext prev, List<Models.TextDiffLine> 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<Models.TextDiffLine> Old { get; } = [];
public List<Models.TextDiffLine> 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)