103 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			103 lines
		
	
	
		
			3.7 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)) | ||
|  |                         { | ||
|  |                             var label = new Label(substring); | ||
|  | #if UNITY_6000_0_OR_NEWER | ||
|  |                             label.style.whiteSpace = WhiteSpace.Pre; | ||
|  | #endif | ||
|  |                             container.Add(label); | ||
|  |                             substring = string.Empty; | ||
|  |                         } | ||
|  | 
 | ||
|  |                         continue; | ||
|  |                     } | ||
|  |                     case k_EndHighlightSeparator when skipCount > 0: | ||
|  |                         skipCount--; | ||
|  |                         continue; | ||
|  |                     case k_EndHighlightSeparator: { | ||
|  |                         var label = new Label(substring); | ||
|  |                         label.AddToClassList(k_HighlightedStyleClassName); | ||
|  | #if UNITY_6000_0_OR_NEWER | ||
|  |                         label.style.whiteSpace = WhiteSpace.Pre; | ||
|  | #endif | ||
|  |                         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); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } |