UnityGame/Library/PackageCache/com.unity.searcher/Editor/Searcher/SearcherHighlighter.cs
2024-10-27 10:53:47 +03:00

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);
}
}
}
}