Forge
csharpdeeb25a2
1namespace CascadeIDE.Services;
2
3/// <summary>Prefix and camelCase-acronym filtering for completion (e.g. SB → StringBuilder, SByte).</summary>
4public static class CSharpCompletionMatcher
5{
6 public enum MatchKind
7 {
8 None = 0,
9 Acronym = 1,
10 Prefix = 2,
11 }
12
13 public static MatchKind GetMatchKind(string name, string prefix)
14 {
15 if (string.IsNullOrEmpty(prefix))
16 return MatchKind.Prefix;
17 if (name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
18 return MatchKind.Prefix;
19 return MatchesCamelCaseAcronym(name, prefix) ? MatchKind.Acronym : MatchKind.None;
20 }
21
22 public static bool Matches(string name, string prefix) =>
23 GetMatchKind(name, prefix) != MatchKind.None;
24
25 public static int CompareByRelevance(string nameA, string nameB, string prefix)
26 {
27 var kindA = GetMatchKind(nameA, prefix);
28 var kindB = GetMatchKind(nameB, prefix);
29 if (kindA != kindB)
30 return kindB.CompareTo(kindA);
31
32 if (prefix.Length > 0)
33 {
34 var posA = nameA.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) ? 0 : IndexOfAcronym(nameA, prefix);
35 var posB = nameB.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) ? 0 : IndexOfAcronym(nameB, prefix);
36 if (posA != posB)
37 return posA.CompareTo(posB);
38 }
39
40 return string.Compare(nameA, nameB, StringComparison.OrdinalIgnoreCase);
41 }
42
43 private static int IndexOfAcronym(string name, string prefix)
44 {
45 var pi = 0;
46 for (var ni = 0; ni < name.Length && pi < prefix.Length; ni++)
47 {
48 if (char.ToUpperInvariant(name[ni]) == char.ToUpperInvariant(prefix[pi]))
49 pi++;
50 }
51
52 return pi == prefix.Length ? 0 : int.MaxValue;
53 }
54
55 private static bool MatchesCamelCaseAcronym(string name, string prefix)
56 {
57 if (prefix.Length == 0)
58 return true;
59
60 var pi = 0;
61 for (var ni = 0; ni < name.Length && pi < prefix.Length; ni++)
62 {
63 if (char.ToUpperInvariant(name[ni]) == char.ToUpperInvariant(prefix[pi]))
64 pi++;
65 }
66
67 return pi == prefix.Length;
68 }
69}
70
View only · write via MCP/CIDE