mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-26 03:40:45 +08:00
refactor: collecting inlines for subjects (#1402)
Instead of checking intersections of inline elements yourself before adding an inline element, the new class `InlineElementCollector` prevents intersections internally. Additionally the inline elements are sorted by the new class, so it's no longer necessary to do this after adding the inline elements.
This commit is contained in:
@@ -121,6 +121,6 @@ namespace SourceGit.Models
|
||||
public class CommitFullMessage
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public List<InlineElement> Inlines { get; set; } = [];
|
||||
public InlineElementCollector Inlines { get; set; } = [];
|
||||
}
|
||||
}
|
||||
|
||||
85
src/Models/InlineElementCollector.cs
Normal file
85
src/Models/InlineElementCollector.cs
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
@@ -46,7 +45,7 @@ namespace SourceGit.Models
|
||||
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;
|
||||
@@ -60,18 +59,6 @@ namespace SourceGit.Models
|
||||
|
||||
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++)
|
||||
|
||||
Reference in New Issue
Block a user