Skip to content

Commit f325aaf

Browse files
committed
refactor: rewrite text-diff
This commit also contains a feature request #1722 Signed-off-by: leo <longshuang@msn.cn>
1 parent 5c33198 commit f325aaf

File tree

10 files changed

+472
-408
lines changed

10 files changed

+472
-408
lines changed

src/Commands/Diff.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@ public partial class Diff : Command
2020

2121
public Diff(string repo, Models.DiffOption opt, int unified, bool ignoreWhitespace)
2222
{
23-
_result.TextDiff = new Models.TextDiff()
24-
{
25-
Repo = repo,
26-
Option = opt,
27-
};
23+
_result.TextDiff = new Models.TextDiff() { Option = opt };
2824

2925
WorkingDirectory = repo;
3026
Context = repo;

src/Models/DiffResult.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System.Collections.Generic;
22
using System.IO;
33
using System.Text.RegularExpressions;
4-
5-
using Avalonia;
64
using Avalonia.Media.Imaging;
75

86
namespace SourceGit.Models
@@ -62,13 +60,10 @@ public bool IsInRange(int idx)
6260
public partial class TextDiff
6361
{
6462
public string File { get; set; } = string.Empty;
63+
public DiffOption Option { get; set; } = null;
6564
public List<TextDiffLine> Lines { get; set; } = new List<TextDiffLine>();
66-
public Vector ScrollOffset { get; set; } = Vector.Zero;
6765
public int MaxLineNumber = 0;
6866

69-
public string Repo { get; set; } = null;
70-
public DiffOption Option { get; set; } = null;
71-
7267
public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombined, bool isOldSide)
7368
{
7469
var rs = new TextDiffSelection();

src/ViewModels/BlockNavigation.cs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,11 @@ public string Indicator
4848
}
4949
}
5050

51-
public BlockNavigation(object context)
51+
public BlockNavigation(List<Models.TextDiffLine> lines)
5252
{
5353
Blocks.Clear();
5454
Current = -1;
5555

56-
var lines = new List<Models.TextDiffLine>();
57-
if (context is Models.TextDiff combined)
58-
lines = combined.Lines;
59-
else if (context is TwoSideTextDiff twoSide)
60-
lines = twoSide.Old;
61-
6256
if (lines.Count == 0)
6357
return;
6458

@@ -96,7 +90,10 @@ public BlockNavigation(object context)
9690

9791
public Block GetCurrentBlock()
9892
{
99-
return (_current >= 0 && _current < Blocks.Count) ? Blocks[_current] : null;
93+
if (_current >= 0 && _current < Blocks.Count)
94+
return Blocks[_current];
95+
96+
return Blocks.Count > 0 ? Blocks[0] : null;
10097
}
10198

10299
public Block GotoFirst()
@@ -105,6 +102,7 @@ public Block GotoFirst()
105102
return null;
106103

107104
Current = 0;
105+
OnPropertyChanged(nameof(Indicator));
108106
return Blocks[_current];
109107
}
110108

@@ -117,6 +115,8 @@ public Block GotoPrev()
117115
Current = 0;
118116
else if (_current > 0)
119117
Current = _current - 1;
118+
119+
OnPropertyChanged(nameof(Indicator));
120120
return Blocks[_current];
121121
}
122122

@@ -127,6 +127,8 @@ public Block GotoNext()
127127

128128
if (_current < Blocks.Count - 1)
129129
Current = _current + 1;
130+
131+
OnPropertyChanged(nameof(Indicator));
130132
return Blocks[_current];
131133
}
132134

@@ -136,9 +138,35 @@ public Block GotoLast()
136138
return null;
137139

138140
Current = Blocks.Count - 1;
141+
OnPropertyChanged(nameof(Indicator));
139142
return Blocks[_current];
140143
}
141144

145+
public void AutoUpdate(int start, int end)
146+
{
147+
if (_current >= 0 && _current < Blocks.Count)
148+
{
149+
var block = Blocks[_current];
150+
if ((block.Start >= start && block.Start <= end) ||
151+
(block.End >= start && block.End <= end) ||
152+
(block.Start <= start && block.End >= end))
153+
return;
154+
}
155+
156+
for (var i = 0; i < Blocks.Count; i++)
157+
{
158+
var block = Blocks[i];
159+
if ((block.Start >= start && block.Start <= end) ||
160+
(block.End >= start && block.End <= end) ||
161+
(block.Start <= start && block.End >= end))
162+
{
163+
Current = i;
164+
OnPropertyChanged(nameof(Indicator));
165+
return;
166+
}
167+
}
168+
}
169+
142170
private int _current = -1;
143171
}
144172
}

src/ViewModels/DiffContext.cs

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using System;
22
using System.IO;
33
using System.Threading.Tasks;
4-
54
using Avalonia.Threading;
6-
75
using CommunityToolkit.Mvvm.ComponentModel;
86

97
namespace SourceGit.ViewModels
@@ -24,7 +22,58 @@ public bool IgnoreWhitespace
2422
{
2523
Preferences.Instance.IgnoreWhitespaceChangesInDiff = value;
2624
OnPropertyChanged();
27-
LoadDiffContent();
25+
26+
if (_isTextDiff)
27+
LoadContent();
28+
}
29+
}
30+
}
31+
32+
public bool ShowEntireFile
33+
{
34+
get => Preferences.Instance.UseFullTextDiff;
35+
set
36+
{
37+
if (value != Preferences.Instance.UseFullTextDiff)
38+
{
39+
Preferences.Instance.UseFullTextDiff = value;
40+
OnPropertyChanged();
41+
42+
if (Content is ITextDiffContext ctx)
43+
{
44+
ctx.ResetScroll();
45+
LoadContent();
46+
}
47+
}
48+
}
49+
}
50+
51+
public bool UseBlockNavigation
52+
{
53+
get => Preferences.Instance.UseBlockNavigationInDiffView;
54+
set
55+
{
56+
if (value != Preferences.Instance.UseBlockNavigationInDiffView)
57+
{
58+
Preferences.Instance.UseBlockNavigationInDiffView = value;
59+
OnPropertyChanged();
60+
(Content as ITextDiffContext)?.ResetBlockNavigation(value);
61+
}
62+
}
63+
}
64+
65+
public bool UseSideBySide
66+
{
67+
get => Preferences.Instance.UseSideBySideDiff;
68+
set
69+
{
70+
if (value != Preferences.Instance.UseSideBySideDiff)
71+
{
72+
Preferences.Instance.UseSideBySideDiff = value;
73+
OnPropertyChanged();
74+
75+
if (Content is ITextDiffContext ctx && ctx.IsSideBySide() != value)
76+
Content = ctx.SwitchMode();
2877
}
2978
}
3079
}
@@ -72,33 +121,49 @@ public DiffContext(string repo, Models.DiffOption option, DiffContext previous =
72121
else
73122
Title = $"{_option.OrgPath}{_option.Path}";
74123

75-
LoadDiffContent();
76-
}
77-
78-
public void ToggleFullTextDiff()
79-
{
80-
Preferences.Instance.UseFullTextDiff = !Preferences.Instance.UseFullTextDiff;
81-
LoadDiffContent();
124+
LoadContent();
82125
}
83126

84127
public void IncrUnified()
85128
{
86129
UnifiedLines = _unifiedLines + 1;
87-
LoadDiffContent();
130+
LoadContent();
88131
}
89132

90133
public void DecrUnified()
91134
{
92135
UnifiedLines = Math.Max(4, _unifiedLines - 1);
93-
LoadDiffContent();
136+
LoadContent();
94137
}
95138

96139
public void OpenExternalMergeTool()
97140
{
98141
new Commands.DiffTool(_repo, _option).Open();
99142
}
100143

101-
private void LoadDiffContent()
144+
public void CheckSettings()
145+
{
146+
if (Content is ITextDiffContext ctx)
147+
{
148+
if ((ShowEntireFile && _info.UnifiedLines != _entireFileLine) ||
149+
(!ShowEntireFile && _info.UnifiedLines == _entireFileLine) ||
150+
(IgnoreWhitespace != _info.IgnoreWhitespace))
151+
{
152+
LoadContent();
153+
return;
154+
}
155+
156+
if (ctx.IsSideBySide() != UseSideBySide)
157+
{
158+
ctx = ctx.SwitchMode();
159+
Content = ctx;
160+
}
161+
162+
ctx.ResetBlockNavigation(UseBlockNavigation);
163+
}
164+
}
165+
166+
private void LoadContent()
102167
{
103168
if (_option.Path.EndsWith('/'))
104169
{
@@ -109,7 +174,7 @@ private void LoadDiffContent()
109174

110175
Task.Run(async () =>
111176
{
112-
var numLines = Preferences.Instance.UseFullTextDiff ? 999999999 : _unifiedLines;
177+
var numLines = Preferences.Instance.UseFullTextDiff ? _entireFileLine : _unifiedLines;
113178
var ignoreWhitespace = Preferences.Instance.IgnoreWhitespaceChangesInDiff;
114179

115180
var latest = await new Commands.Diff(_repo, _option, numLines, ignoreWhitespace)
@@ -228,12 +293,23 @@ private void LoadDiffContent()
228293

229294
Dispatcher.UIThread.Post(() =>
230295
{
231-
if (_content is Models.TextDiff old && rs is Models.TextDiff cur && old.File == cur.File)
232-
cur.ScrollOffset = old.ScrollOffset;
233-
234296
FileModeChange = latest.FileModeChange;
235-
Content = rs;
236-
IsTextDiff = rs is Models.TextDiff;
297+
298+
if (rs is Models.TextDiff cur)
299+
{
300+
IsTextDiff = true;
301+
302+
var hasBlockNavigation = Preferences.Instance.UseBlockNavigationInDiffView;
303+
if (Preferences.Instance.UseSideBySideDiff)
304+
Content = new TwoSideTextDiff(cur, hasBlockNavigation, _content as TwoSideTextDiff);
305+
else
306+
Content = new CombinedTextDiff(cur, hasBlockNavigation, _content as CombinedTextDiff);
307+
}
308+
else
309+
{
310+
IsTextDiff = false;
311+
Content = rs;
312+
}
237313
});
238314
});
239315
}
@@ -279,6 +355,7 @@ public bool IsSame(Info other)
279355
}
280356
}
281357

358+
private readonly int _entireFileLine = 999999999;
282359
private readonly string _repo;
283360
private readonly Models.DiffOption _option = null;
284361
private string _fileModeChange = string.Empty;

0 commit comments

Comments
 (0)