diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index 6c381df35..f629947a3 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -2,6 +2,7 @@ using System.IO; using System.Text.RegularExpressions; using Avalonia.Media.Imaging; +using SourceGit.ViewModels; namespace SourceGit.Models { @@ -49,6 +50,7 @@ public class TextDiffSelection public bool HasChanges { get; set; } = false; public int IgnoredAdds { get; set; } = 0; public int IgnoredDeletes { get; set; } = 0; + public bool HasRemainingChanges { get; set; } = false; } public partial class TextDiff @@ -65,10 +67,17 @@ public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombin for (int i = 0; i < startLine - 1; i++) { var line = Lines[i]; - if (line.Type == TextDiffLineType.Added) - rs.IgnoredAdds++; - else if (line.Type == TextDiffLineType.Deleted) - rs.IgnoredDeletes++; + switch (line.Type) + { + case TextDiffLineType.Added: + rs.IgnoredAdds++; + rs.HasRemainingChanges = true; + break; + case TextDiffLineType.Deleted: + rs.IgnoredDeletes++; + rs.HasRemainingChanges = true; + break; + } } for (int i = startLine - 1; i < endLine; i++) @@ -92,6 +101,18 @@ public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombin } } + for (var i = endLine; i < Lines.Count; i++) + { + var line = Lines[i]; + switch (line.Type) + { + case TextDiffLineType.Added: + case TextDiffLineType.Deleted: + rs.HasRemainingChanges = true; + break; + } + } + return rs; } diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index 8f040310d..4e6eece52 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -4,6 +4,7 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; +using Avalonia.VisualTree; namespace SourceGit.Views { @@ -610,5 +611,17 @@ private async void OnBisectCommand(object sender, RoutedEventArgs e) e.Handled = true; } + + public void SelectNextStagedChangeWithoutSelection() + { + this.FindDescendantOfType() + ?.SelectNextStagedChangeWithoutSelection(); + } + + public void SelectNextUnstagedChangeWithoutSelection() + { + this.FindDescendantOfType() + ?.SelectNextUnstagedChangeWithoutSelection(); + } } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 164ad3cac..052294024 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1496,6 +1496,10 @@ private async void OnStageChunk(object _1, RoutedEventArgs _2) await new Commands.Apply(repo.FullPath, tmpFile, true, "nowarn", "--cache --index").ExecAsync(); File.Delete(tmpFile); + if (!selection.HasRemainingChanges) + { + repoView.SelectNextUnstagedChangeWithoutSelection(); + } repo.MarkWorkingCopyDirtyManually(); } @@ -1526,6 +1530,11 @@ private async void OnUnstageChunk(object _1, RoutedEventArgs _2) await new Commands.Apply(repo.FullPath, tmpFile, true, "nowarn", "--cache --index --reverse").ExecAsync(); File.Delete(tmpFile); + if (!selection.HasRemainingChanges) + { + repoView.SelectNextStagedChangeWithoutSelection(); + } + repo.MarkWorkingCopyDirtyManually(); } @@ -1563,6 +1572,10 @@ private async void OnDiscardChunk(object _1, RoutedEventArgs _2) await new Commands.Apply(repo.FullPath, tmpFile, true, "nowarn", "--reverse").ExecAsync(); File.Delete(tmpFile); + if (selection.HasRemainingChanges) + { + repoView.SelectNextUnstagedChangeWithoutSelection(); + } repo.MarkWorkingCopyDirtyManually(); } } diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs index 5840d247a..472f0d4f5 100644 --- a/src/Views/WorkingCopy.axaml.cs +++ b/src/Views/WorkingCopy.axaml.cs @@ -79,6 +79,15 @@ private async void OnUnstagedChangeDoubleTapped(object _, RoutedEventArgs e) } } + public void SelectNextUnstagedChangeWithoutSelection() + { + if (DataContext is ViewModels.WorkingCopy vm) + { + var next = UnstagedChangesView.GetNextChangeWithoutSelection(); + vm.SelectedUnstaged = next != null ? [next] : []; + } + } + private async void OnStagedChangeDoubleTapped(object _, RoutedEventArgs e) { if (DataContext is ViewModels.WorkingCopy vm) @@ -89,6 +98,15 @@ private async void OnStagedChangeDoubleTapped(object _, RoutedEventArgs e) e.Handled = true; } } + + public void SelectNextStagedChangeWithoutSelection() + { + if (DataContext is ViewModels.WorkingCopy vm) + { + var next = StagedChangesView.GetNextChangeWithoutSelection(); + vm.SelectedStaged = next != null ? [next] : []; + } + } private async void OnUnstagedKeyDown(object _, KeyEventArgs e) {