Skip to content

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)