Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0007072

Browse files
committed
Implemented change-block navigation
1 parent d0dc9ac commit 0007072

File tree

7 files changed

+228
-33
lines changed

7 files changed

+228
-33
lines changed

‎src/Commands/Diff.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public Models.DiffResult Result()
5151
_result.TextDiff.MaxLineNumber = Math.Max(_newLine, _oldLine);
5252
}
5353

54+
if (_result.TextDiff != null)
55+
_result.TextDiff.ProcessChangeBlocks();
56+
5457
return _result;
5558
}
5659

‎src/Models/DiffResult.cs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Text;
33
using System.Text.RegularExpressions;
44

5+
using CommunityToolkit.Mvvm.ComponentModel;
6+
57
using Avalonia;
68
using Avalonia.Media.Imaging;
79

@@ -59,16 +61,70 @@ public bool IsInRange(int idx)
5961
}
6062
}
6163

62-
public partial class TextDiff
64+
public class TextDiffChangeBlock
65+
{
66+
public TextDiffChangeBlock(int startLine, int endLine)
67+
{
68+
StartLine = startLine;
69+
EndLine = endLine;
70+
}
71+
72+
public int StartLine { get; set; } = 0;
73+
public int EndLine { get; set; } = 0;
74+
75+
public bool IsInRange(int line)
76+
{
77+
return line >= StartLine && line <= EndLine;
78+
}
79+
}
80+
81+
public partial class TextDiff : ObservableObject
6382
{
6483
public string File { get; set; } = string.Empty;
6584
public List<TextDiffLine> Lines { get; set; } = new List<TextDiffLine>();
6685
public Vector ScrollOffset { get; set; } = Vector.Zero;
6786
public int MaxLineNumber = 0;
6887

88+
public int CurrentChangeBlockIdx
89+
{
90+
get => _currentChangeBlockIdx;
91+
set => SetProperty(ref _currentChangeBlockIdx, value);
92+
}
93+
6994
public string Repo { get; set; } = null;
7095
public DiffOption Option { get; set; } = null;
7196

97+
public List<TextDiffChangeBlock> ChangeBlocks { get; set; } = [];
98+
99+
public void ProcessChangeBlocks()
100+
{
101+
ChangeBlocks.Clear();
102+
int lineIdx = 0, blockStartIdx = 0;
103+
bool isNewBlock = true;
104+
foreach (var line in Lines)
105+
{
106+
lineIdx++;
107+
if (line.Type == Models.TextDiffLineType.Added ||
108+
line.Type == Models.TextDiffLineType.Deleted ||
109+
line.Type == Models.TextDiffLineType.None) // Empty
110+
{
111+
if (isNewBlock)
112+
{
113+
isNewBlock = false;
114+
blockStartIdx = lineIdx;
115+
}
116+
}
117+
else
118+
{
119+
if (!isNewBlock)
120+
{
121+
ChangeBlocks.Add(new TextDiffChangeBlock(blockStartIdx, lineIdx - 1));
122+
isNewBlock = true;
123+
}
124+
}
125+
}
126+
}
127+
72128
public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombined, bool isOldSide)
73129
{
74130
var rs = new TextDiffSelection();
@@ -626,6 +682,8 @@ private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffL
626682
return true;
627683
}
628684

685+
private int _currentChangeBlockIdx = -1; // NOTE: Use -1 as "not set".
686+
629687
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
630688
private static partial Regex REG_INDICATOR();
631689
}

‎src/ViewModels/DiffContext.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,22 @@ public DiffContext(string repo, Models.DiffOption option, DiffContext previous =
7575

7676
public void PrevChange()
7777
{
78-
// To be implemented...
78+
if (_content is Models.TextDiff textDiff)
79+
{
80+
if (textDiff.CurrentChangeBlockIdx > 0)
81+
textDiff.CurrentChangeBlockIdx--;
82+
else if (textDiff.CurrentChangeBlockIdx == -1 && textDiff.ChangeBlocks.Count > 0)
83+
textDiff.CurrentChangeBlockIdx = 0; // Jump to first change block
84+
}
7985
}
8086

8187
public void NextChange()
8288
{
83-
// To be implemented...
89+
if (_content is Models.TextDiff textDiff)
90+
{
91+
if (textDiff.CurrentChangeBlockIdx < textDiff.ChangeBlocks.Count - 1)
92+
textDiff.CurrentChangeBlockIdx++;
93+
}
8494
}
8595

8696
public void ToggleFullTextDiff()

‎src/ViewModels/TwoSideTextDiff.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,43 @@ public TwoSideTextDiff(Models.TextDiff diff, TwoSideTextDiff previous = null)
4545

4646
FillEmptyLines();
4747

48+
ProcessChangeBlocks();
49+
4850
if (previous != null && previous.File == File)
4951
_syncScrollOffset = previous._syncScrollOffset;
5052
}
5153

54+
public List<Models.TextDiffChangeBlock> ChangeBlocks { get; set; } = [];
55+
56+
public void ProcessChangeBlocks()
57+
{
58+
ChangeBlocks.Clear();
59+
int lineIdx = 0, blockStartIdx = 0;
60+
bool isNewBlock = true;
61+
foreach (var line in Old) // NOTE: Same block size in both Old and New lines.
62+
{
63+
lineIdx++;
64+
if (line.Type == Models.TextDiffLineType.Added ||
65+
line.Type == Models.TextDiffLineType.Deleted ||
66+
line.Type == Models.TextDiffLineType.None) // Empty
67+
{
68+
if (isNewBlock)
69+
{
70+
isNewBlock = false;
71+
blockStartIdx = lineIdx;
72+
}
73+
}
74+
else
75+
{
76+
if (!isNewBlock)
77+
{
78+
ChangeBlocks.Add(new Models.TextDiffChangeBlock(blockStartIdx, lineIdx - 1));
79+
isNewBlock = true;
80+
}
81+
}
82+
}
83+
}
84+
5285
public void ConvertsToCombinedRange(Models.TextDiff combined, ref int startLine, ref int endLine, bool isOldSide)
5386
{
5487
endLine = Math.Min(endLine, combined.Lines.Count - 1);

‎src/Views/DiffView.axaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@
241241
<DataTemplate DataType="m:TextDiff">
242242
<v:TextDiffView
243243
UseSideBySideDiff="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSideBySideDiff, Mode=OneWay}"
244-
UseFullTextDiff="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFullTextDiff, Mode=OneWay}"/>
244+
UseFullTextDiff="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFullTextDiff, Mode=OneWay}"
245+
CurrentChangeBlockIdx="{Binding CurrentChangeBlockIdx, Mode=OneWay}"/>
245246
</DataTemplate>
246247

247248
<!-- Empty or only EOL changes -->

‎src/Views/TextDiffView.axaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting}"
2828
WordWrap="{Binding Source={x:Static vm:Preference.Instance}, Path=EnableDiffViewWordWrap}"
2929
ShowHiddenSymbols="{Binding Source={x:Static vm:Preference.Instance}, Path=ShowHiddenSymbolsInDiffView}"
30+
CurrentChangeBlockIdx="{Binding #ThisControl.CurrentChangeBlockIdx}"
3031
EnableChunkSelection="{Binding #ThisControl.EnableChunkSelection}"
3132
SelectedChunk="{Binding #ThisControl.SelectedChunk, Mode=TwoWay}"/>
3233
</DataTemplate>
@@ -49,6 +50,7 @@
4950
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting}"
5051
WordWrap="False"
5152
ShowHiddenSymbols="{Binding Source={x:Static vm:Preference.Instance}, Path=ShowHiddenSymbolsInDiffView}"
53+
CurrentChangeBlockIdx="{Binding #ThisControl.CurrentChangeBlockIdx}"
5254
EnableChunkSelection="{Binding #ThisControl.EnableChunkSelection}"
5355
SelectedChunk="{Binding #ThisControl.SelectedChunk, Mode=TwoWay}"/>
5456

@@ -70,6 +72,7 @@
7072
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preference.Instance}, Path=UseSyntaxHighlighting}"
7173
WordWrap="False"
7274
ShowHiddenSymbols="{Binding Source={x:Static vm:Preference.Instance}, Path=ShowHiddenSymbolsInDiffView}"
75+
CurrentChangeBlockIdx="{Binding #ThisControl.CurrentChangeBlockIdx}"
7376
EnableChunkSelection="{Binding #ThisControl.EnableChunkSelection}"
7477
SelectedChunk="{Binding #ThisControl.SelectedChunk, Mode=TwoWay}"/>
7578
</Grid>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /