96 lines
3.4 KiB
C#
96 lines
3.4 KiB
C#
|
using System;
|
||
|
using System.Text.RegularExpressions;
|
||
|
using UnityEngine.UIElements;
|
||
|
|
||
|
namespace UnityEditor.Searcher
|
||
|
{
|
||
|
static class SearcherHighlighter
|
||
|
{
|
||
|
const char k_StartHighlightSeparator = '{';
|
||
|
const char k_EndHighlightSeparator = '}';
|
||
|
const string k_HighlightedStyleClassName = "Highlighted";
|
||
|
|
||
|
public static void HighlightTextBasedOnQuery(VisualElement container, string text, string query)
|
||
|
{
|
||
|
var formattedText = text;
|
||
|
var queryParts = query.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
|
||
|
var regex = string.Empty;
|
||
|
for (var index = 0; index < queryParts.Length; index++)
|
||
|
{
|
||
|
var queryPart = queryParts[index];
|
||
|
regex += $"({Regex.Escape(queryPart)})";
|
||
|
if (index < queryParts.Length - 1)
|
||
|
regex += "|";
|
||
|
}
|
||
|
|
||
|
var matches = Regex.Matches(formattedText, regex, RegexOptions.IgnoreCase);
|
||
|
foreach (Match match in matches)
|
||
|
{
|
||
|
formattedText = formattedText.Replace(match.Value,
|
||
|
$"{k_StartHighlightSeparator}{match.Value}{k_EndHighlightSeparator}");
|
||
|
}
|
||
|
|
||
|
BuildHighlightLabels(container, formattedText);
|
||
|
}
|
||
|
|
||
|
static void BuildHighlightLabels(VisualElement container, string formattedHighlightText)
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(formattedHighlightText))
|
||
|
return;
|
||
|
|
||
|
var substring = string.Empty;
|
||
|
var highlighting = false;
|
||
|
var skipCount = 0;
|
||
|
foreach (var character in formattedHighlightText.ToCharArray())
|
||
|
{
|
||
|
switch (character)
|
||
|
{
|
||
|
// Skip embedded separators
|
||
|
// Ex:
|
||
|
// Query: middle e
|
||
|
// Text: Middle Eastern
|
||
|
// Formatted Text: {Middl{e}} {E}ast{e}rn
|
||
|
// ^ ^
|
||
|
case k_StartHighlightSeparator when highlighting:
|
||
|
skipCount++;
|
||
|
continue;
|
||
|
case k_StartHighlightSeparator: {
|
||
|
highlighting = true;
|
||
|
if (!string.IsNullOrEmpty(substring))
|
||
|
{
|
||
|
container.Add(new Label(substring));
|
||
|
substring = string.Empty;
|
||
|
}
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
case k_EndHighlightSeparator when skipCount > 0:
|
||
|
skipCount--;
|
||
|
continue;
|
||
|
case k_EndHighlightSeparator: {
|
||
|
var label = new Label(substring);
|
||
|
label.AddToClassList(k_HighlightedStyleClassName);
|
||
|
container.Add(label);
|
||
|
|
||
|
highlighting = false;
|
||
|
substring = string.Empty;
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
default:
|
||
|
substring += character;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!string.IsNullOrEmpty(substring))
|
||
|
{
|
||
|
var label = new Label(substring);
|
||
|
if (highlighting)
|
||
|
label.AddToClassList(k_HighlightedStyleClassName);
|
||
|
container.Add(label);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|