Skip to content

Commit a744a93

Browse files
committed
feature: auto-complete git commit message keywords, such as Co-authored-by:
Signed-off-by: leo <longshuang@msn.cn>
1 parent 54fedef commit a744a93

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

src/Resources/Styles.axaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
xmlns:v="using:SourceGit.Views"
66
xmlns:c="using:SourceGit.Converters"
77
xmlns:ae="using:AvaloniaEdit"
8+
xmlns:acc="using:AvaloniaEdit.CodeCompletion"
89
xmlns:aee="using:AvaloniaEdit.Editing"
910
xmlns:aes="using:AvaloniaEdit.Search">
1011
<Design.PreviewWith>
@@ -1347,4 +1348,16 @@
13471348
<Setter Property="IsVisible" Value="False"/>
13481349
</Style>
13491350
</Style>
1351+
1352+
<Style Selector="acc|CompletionListBox">
1353+
<Setter Property="Background" Value="{DynamicResource Brush.Popup}"/>
1354+
<Setter Property="Padding" Value="8,4"/>
1355+
<Setter Property="CornerRadius" Value="4"/>
1356+
</Style>
1357+
1358+
<Style Selector="acc|CompletionListBox ListBoxItem">
1359+
<Setter Property="Height" Value="24"/>
1360+
<Setter Property="Margin" Value="0,2"/>
1361+
<Setter Property="CornerRadius" Value="4"/>
1362+
</Style>
13501363
</Styles>

src/Views/CommitMessageToolBox.axaml.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,52 @@
1111
using Avalonia.Media;
1212

1313
using AvaloniaEdit;
14+
using AvaloniaEdit.CodeCompletion;
1415
using AvaloniaEdit.Document;
1516
using AvaloniaEdit.Editing;
1617
using AvaloniaEdit.Rendering;
18+
using AvaloniaEdit.Utils;
1719

1820
namespace SourceGit.Views
1921
{
22+
public class CommitMessageCodeCompletionData : ICompletionData
23+
{
24+
public IImage Image
25+
{
26+
get => null;
27+
}
28+
29+
public string Text
30+
{
31+
get;
32+
}
33+
34+
public object Content
35+
{
36+
get => Text;
37+
}
38+
39+
public object Description
40+
{
41+
get => null;
42+
}
43+
44+
public double Priority
45+
{
46+
get => 0;
47+
}
48+
49+
public CommitMessageCodeCompletionData(string text)
50+
{
51+
Text = text;
52+
}
53+
54+
public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
55+
{
56+
textArea.Document.Replace(completionSegment, Text);
57+
}
58+
}
59+
2060
public class CommitMessageTextEditor : TextEditor
2161
{
2262
public static readonly StyledProperty<string> CommitMessageProperty =
@@ -183,9 +223,50 @@ protected override void OnTextChanged(EventArgs e)
183223
{
184224
base.OnTextChanged(e);
185225

226+
if (!IsLoaded)
227+
return;
228+
186229
_isEditing = true;
187230
SetCurrentValue(CommitMessageProperty, Text);
188231
_isEditing = false;
232+
233+
var caretOffset = CaretOffset;
234+
var start = caretOffset;
235+
while (start > 0 && !char.IsWhiteSpace(Text[start - 1]))
236+
start--;
237+
238+
if (caretOffset == start)
239+
{
240+
_completionWnd?.Close();
241+
return;
242+
}
243+
244+
var word = Text.Substring(start, caretOffset - start);
245+
var matches = new List<CommitMessageCodeCompletionData>();
246+
foreach (var keyword in _keywords)
247+
{
248+
if (keyword.StartsWith(word, StringComparison.OrdinalIgnoreCase) && keyword.Length != word.Length)
249+
matches.Add(new(keyword));
250+
}
251+
252+
if (matches.Count > 0)
253+
{
254+
if (_completionWnd == null)
255+
{
256+
_completionWnd = new CompletionWindow(TextArea);
257+
_completionWnd.Closed += (_, ev) => _completionWnd = null;
258+
_completionWnd.Show();
259+
}
260+
261+
_completionWnd.CompletionList.CompletionData.Clear();
262+
_completionWnd.CompletionList.CompletionData.AddRange(matches);
263+
_completionWnd.StartOffset = start;
264+
_completionWnd.EndOffset = caretOffset;
265+
}
266+
else
267+
{
268+
_completionWnd?.Close();
269+
}
189270
}
190271

191272
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
@@ -235,7 +316,9 @@ private void OnTextViewVisualLinesChanged(object sender, EventArgs e)
235316
InvalidateVisual();
236317
}
237318

319+
private readonly List<string> _keywords = ["git", "GitHub", "GitLab", "Acked-by: ", "Co-authored-by: ", "Reviewed-by: ", "Signed-off-by: ", "BREAKING CHANGE: "];
238320
private bool _isEditing = false;
321+
private CompletionWindow _completionWnd = null;
239322
}
240323

241324
public partial class CommitMessageToolBox : UserControl

0 commit comments

Comments
 (0)