Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Models/Commit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,6 @@ public void ParseDecorators(string data)
public class CommitFullMessage
{
public string Message { get; set; } = string.Empty;
public List<InlineElement> Inlines { get; set; } = [];
public InlineElementCollector Inlines { get; set; } = [];
}
}
85 changes: 85 additions & 0 deletions src/Models/InlineElementCollector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

namespace SourceGit.Models
{
public class InlineElementCollector : IEnumerable<InlineElement>
{
private readonly List<InlineElement> _implementation = [];

public void Clear()
{
_implementation.Clear();

AssertInvariant();
}

public int Count => _implementation.Count;

public void Add(InlineElement element)
{

var index = FindIndex(element.Start);
if (!IsIntersection(index, element.Start, element.Length))
_implementation.Insert(index, element);

AssertInvariant();
}

[Conditional("DEBUG")]
private void AssertInvariant()
{
if (_implementation.Count == 0)
return;

for (var index = 1; index < _implementation.Count; index++)
{
var prev = _implementation[index - 1];
var curr = _implementation[index];

Debug.Assert(prev.Start + prev.Length <= curr.Start);
}
}

public InlineElement Lookup(int position)
{
var index = FindIndex(position);
return IsIntersection(index, position, 1)
? _implementation[index]
: null;
}

private int FindIndex(int start)
{
var index = 0;
while (index < _implementation.Count && _implementation[index].Start <= start)
index++;

return index;
}

private bool IsIntersection(int index, int start, int length)
{
if (index > 0)
{
var predecessor = _implementation[index - 1];
if (predecessor.Start + predecessor.Length >= start)
return true;
}

if (index < _implementation.Count)
{
var successor = _implementation[index];
if (start + length >= successor.Start)
return true;
}

return false;
}

public IEnumerator<InlineElement> GetEnumerator() => _implementation.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
17 changes: 2 additions & 15 deletions src/Models/IssueTrackerRule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;

using CommunityToolkit.Mvvm.ComponentModel;

Expand Down Expand Up @@ -46,7 +45,7 @@ public string URLTemplate
set => SetProperty(ref _urlTemplate, value);
}

public void Matches(List<InlineElement> outs, string message)
public void Matches(InlineElementCollector outs, string message)
{
if (_regex == null || string.IsNullOrEmpty(_urlTemplate))
return;
Expand All @@ -60,18 +59,6 @@ public void Matches(List<InlineElement> outs, string message)

var start = match.Index;
var len = match.Length;
var intersect = false;
foreach (var exist in outs)
{
if (exist.Intersect(start, len))
{
intersect = true;
break;
}
}

if (intersect)
continue;

var link = _urlTemplate;
for (var j = 1; j < match.Groups.Count; j++)
Expand Down
31 changes: 2 additions & 29 deletions src/ViewModels/CommitDetail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,9 @@ private void Refresh()
});
}

private List<Models.InlineElement> ParseInlinesInMessage(string message)
private Models.InlineElementCollector ParseInlinesInMessage(string message)
{
var inlines = new List<Models.InlineElement>();
var inlines = new Models.InlineElementCollector();
if (_repo.Settings.IssueTrackerRules is { Count: > 0 } rules)
{
foreach (var rule in rules)
Expand All @@ -638,18 +638,6 @@ private void Refresh()

var start = match.Index;
var len = match.Length;
var intersect = false;
foreach (var link in inlines)
{
if (link.Intersect(start, len))
{
intersect = true;
break;
}
}

if (intersect)
continue;

var url = message.Substring(start, len);
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
Expand All @@ -665,28 +653,13 @@ private void Refresh()

var start = match.Index;
var len = match.Length;
var intersect = false;
foreach (var link in inlines)
{
if (link.Intersect(start, len))
{
intersect = true;
break;
}
}

if (intersect)
continue;

var sha = match.Groups[1].Value;
var isCommitSHA = new Commands.IsCommitSHA(_repo.FullPath, sha).Result();
if (isCommitSHA)
inlines.Add(new Models.InlineElement(Models.InlineElementType.CommitSHA, start, len, sha));
}

if (inlines.Count > 0)
inlines.Sort((l, r) => l.Start - r.Start);

return inlines;
}

Expand Down
37 changes: 18 additions & 19 deletions src/Views/CommitMessagePresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,26 +95,11 @@ protected override void OnPointerMoved(PointerEventArgs e)
point = new Point(x, y);

var pos = TextLayout.HitTestPoint(point).TextPosition;
foreach (var link in links)
{
if (!link.Intersect(pos, 1))
continue;

if (link == _lastHover)
return;

SetCurrentValue(CursorProperty, Cursor.Parse("Hand"));

_lastHover = link;
if (link.Type == Models.InlineElementType.Link)
ToolTip.SetTip(this, link.Link);
else
ProcessHoverCommitLink(link);

return;
}

ClearHoveredIssueLink();
if (links.Lookup(pos) is { } link)
SetHoveredIssueLink(link);
else
ClearHoveredIssueLink();
}
}

Expand Down Expand Up @@ -291,6 +276,20 @@ private void ProcessHoverCommitLink(Models.InlineElement link)
}
}

private void SetHoveredIssueLink(Models.InlineElement link)
{
if (link == _lastHover)
return;

SetCurrentValue(CursorProperty, Cursor.Parse("Hand"));

_lastHover = link;
if (link.Type == Models.InlineElementType.Link)
ToolTip.SetTip(this, link.Link);
else
ProcessHoverCommitLink(link);
}

private void ClearHoveredIssueLink()
{
if (_lastHover != null)
Expand Down
16 changes: 1 addition & 15 deletions src/Views/CommitSubjectPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,13 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang

var start = match.Index;
var len = match.Length;
var intersect = false;
foreach (var exist in _elements)
{
if (exist.Intersect(start, len))
{
intersect = true;
break;
}
}

if (intersect)
continue;

_elements.Add(new Models.InlineElement(Models.InlineElementType.Code, start, len, string.Empty));
}

var rules = IssueTrackerRules ?? [];
foreach (var rule in rules)
rule.Matches(_elements, subject);

_elements.Sort((l, r) => l.Start - r.Start);
_needRebuildInlines = true;
InvalidateVisual();
}
Expand Down Expand Up @@ -364,7 +350,7 @@ public Inline(double x, FormattedText text, Models.InlineElement elem)
}
}

private List<Models.InlineElement> _elements = [];
private Models.InlineElementCollector _elements = [];
private List<Inline> _inlines = [];
private Models.InlineElement _lastHover = null;
private bool _needRebuildInlines = false;
Expand Down
Loading