diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml
index 06525abd..e0627ad8 100644
--- a/src/Views/DiffView.axaml
+++ b/src/Views/DiffView.axaml
@@ -34,8 +34,24 @@
+
+
+
+
@@ -81,9 +94,7 @@
@@ -97,14 +108,14 @@
@@ -112,16 +123,14 @@
-
diff --git a/src/Views/DiffView.axaml.cs b/src/Views/DiffView.axaml.cs
index 860627d3..7184ec44 100644
--- a/src/Views/DiffView.axaml.cs
+++ b/src/Views/DiffView.axaml.cs
@@ -1,4 +1,6 @@
using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.VisualTree;
namespace SourceGit.Views
{
@@ -8,5 +10,31 @@ namespace SourceGit.Views
{
InitializeComponent();
}
+
+ private void OnGotoPrevChange(object _, RoutedEventArgs e)
+ {
+ var textDiff = this.FindDescendantOfType();
+ if (textDiff == null)
+ return;
+
+ textDiff.GotoPrevChange();
+ if (textDiff is SingleSideTextDiffPresenter presenter)
+ presenter.ForceSyncScrollOffset();
+
+ e.Handled = true;
+ }
+
+ private void OnGotoNextChange(object _, RoutedEventArgs e)
+ {
+ var textDiff = this.FindDescendantOfType();
+ if (textDiff == null)
+ return;
+
+ textDiff.GotoNextChange();
+ if (textDiff is SingleSideTextDiffPresenter presenter)
+ presenter.ForceSyncScrollOffset();
+
+ e.Handled = true;
+ }
}
}
diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs
index 913a6340..fb2693a8 100644
--- a/src/Views/TextDiffView.axaml.cs
+++ b/src/Views/TextDiffView.axaml.cs
@@ -498,6 +498,108 @@ namespace SourceGit.Views
{
}
+ public void GotoPrevChange()
+ {
+ var view = TextArea.TextView;
+ var lines = GetLines();
+ var firstLineIdx = lines.Count;
+ foreach (var line in view.VisualLines)
+ {
+ if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
+ continue;
+
+ var index = line.FirstDocumentLine.LineNumber - 1;
+ if (index >= lines.Count)
+ continue;
+
+ if (firstLineIdx > index)
+ firstLineIdx = index;
+ }
+
+ var firstLineType = lines[firstLineIdx].Type;
+ var isChangeFirstLine = firstLineType != Models.TextDiffLineType.Normal && firstLineType != Models.TextDiffLineType.Indicator;
+ if (isChangeFirstLine)
+ {
+ for (var i = firstLineIdx - 1; i >= 0; i--)
+ {
+ var prevType = lines[i].Type;
+ if (prevType == Models.TextDiffLineType.Normal || prevType == Models.TextDiffLineType.Indicator)
+ {
+ ScrollToLine(i + 2);
+ return;
+ }
+ }
+ }
+ else
+ {
+ var prevChangeEnd = -1;
+ for (var i = firstLineIdx - 1; i >= 0; i--)
+ {
+ var prevType = lines[i].Type;
+ if (prevType == Models.TextDiffLineType.None ||
+ prevType == Models.TextDiffLineType.Added ||
+ prevType == Models.TextDiffLineType.Deleted)
+ {
+ prevChangeEnd = i;
+ break;
+ }
+ }
+
+ if (prevChangeEnd <= 0)
+ return;
+
+ for (var i = prevChangeEnd - 1; i >= 0; i--)
+ {
+ var prevType = lines[i].Type;
+ if (prevType == Models.TextDiffLineType.Normal || prevType == Models.TextDiffLineType.Indicator)
+ {
+ ScrollToLine(i + 2);
+ return;
+ }
+ }
+ }
+ }
+
+ public void GotoNextChange()
+ {
+ var view = TextArea.TextView;
+ var lines = GetLines();
+ var lastLineIdx = -1;
+ foreach (var line in view.VisualLines)
+ {
+ if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
+ continue;
+
+ var index = line.FirstDocumentLine.LineNumber - 1;
+ if (index >= lines.Count)
+ continue;
+
+ if (lastLineIdx < index)
+ lastLineIdx = index;
+ }
+
+ var lastLineType = lines[lastLineIdx].Type;
+ var findNormalLine = lastLineType == Models.TextDiffLineType.Normal || lastLineType == Models.TextDiffLineType.Indicator;
+ for (var idx = lastLineIdx + 1; idx < lines.Count; idx++)
+ {
+ var nextType = lines[idx].Type;
+ if (nextType == Models.TextDiffLineType.None ||
+ nextType == Models.TextDiffLineType.Added ||
+ nextType == Models.TextDiffLineType.Deleted)
+ {
+ if (findNormalLine)
+ {
+ ScrollToLine(idx + 1);
+ return;
+ }
+ }
+ else if (!findNormalLine)
+ {
+ findNormalLine = true;
+ }
+ }
+ }
+
public override void Render(DrawingContext context)
{
base.Render(context);
@@ -968,6 +1070,12 @@ namespace SourceGit.Views
TextArea.LeftMargins.Add(new LineModifyTypeMargin());
}
+ public void ForceSyncScrollOffset()
+ {
+ if (DataContext is ViewModels.TwoSideTextDiff diff)
+ diff.SyncScrollOffset = _scrollViewer.Offset;
+ }
+
public override List GetLines()
{
if (DataContext is ViewModels.TwoSideTextDiff diff)