add setting searching by mod name

This commit is contained in:
neilmjain committed 2026-10-15 16:37:00 -04:00
1 parent bcacbad0e6
commit a7585ee2fe
1 file changed
+73 -7
+73 -7
View File
@@ -18,9 +18,14 @@ internal sealed record GuideOptionEntry(
string Value, string Value,
AbstractOptionGroup Group, AbstractOptionGroup Group,
string GroupName, string GroupName,
string ModAbbreviation); string ModAbbreviation,
IReadOnlyList<string> ModSearchTerms);
internal sealed class GuideOptionPage(AbstractOptionGroup group, string modAbbreviation, IReadOnlyList<GuideOptionEntry> entries) internal sealed class GuideOptionPage(
AbstractOptionGroup group,
string modAbbreviation,
IReadOnlyList<string> modSearchTerms,
IReadOnlyList<GuideOptionEntry> entries)
{ {
public AbstractOptionGroup Group { get; } = group; public AbstractOptionGroup Group { get; } = group;
@@ -30,6 +35,8 @@ internal sealed class GuideOptionPage(AbstractOptionGroup group, string modAbbre
public string ModAbbreviation { get; } = modAbbreviation; public string ModAbbreviation { get; } = modAbbreviation;
public IReadOnlyList<string> ModSearchTerms { get; } = modSearchTerms;
public IReadOnlyList<GuideOptionEntry> Entries { get; } = entries; public IReadOnlyList<GuideOptionEntry> Entries { get; } = entries;
} }
@@ -44,7 +51,10 @@ internal static class GuideOptionPages
var groups = MiraPluginManager.Instance.PluginsWithOptionsOrGameModes var groups = MiraPluginManager.Instance.PluginsWithOptionsOrGameModes
.SelectMany(plugin => plugin.InternalOptionGroups .SelectMany(plugin => plugin.InternalOptionGroups
.Where(group => group.ShowInMatchInfoGuide && IsSettingsGroup(group, mode) && SafeGroupVisible(group)) .Where(group => group.ShowInMatchInfoGuide && IsSettingsGroup(group, mode) && SafeGroupVisible(group))
.Select(group => (Group: group, ModAbbreviation: plugin.MiraPlugin.GetAbbreviatedModName()))) .Select(group => (
Plugin: plugin,
Group: group,
ModAbbreviation: plugin.MiraPlugin.GetAbbreviatedModName())))
.OrderBy(item => GetMenuOrder(item.Group.ParentMenu)) .OrderBy(item => GetMenuOrder(item.Group.ParentMenu))
.ThenBy(item => item.Group.GroupPriority) .ThenBy(item => item.Group.GroupPriority)
.ThenBy(item => item.Group.GroupName, StringComparer.OrdinalIgnoreCase) .ThenBy(item => item.Group.GroupName, StringComparer.OrdinalIgnoreCase)
@@ -53,6 +63,7 @@ internal static class GuideOptionPages
foreach (var item in groups) foreach (var item in groups)
{ {
var groupName = item.Group.GroupName.Translate(); var groupName = item.Group.GroupName.Translate();
var modSearchTerms = GetModSearchTerms(item.Plugin, item.Group);
var entries = new List<GuideOptionEntry>(); var entries = new List<GuideOptionEntry>();
foreach (var option in item.Group.Options) foreach (var option in item.Group.Options)
@@ -62,7 +73,13 @@ internal static class GuideOptionPages
continue; continue;
} }
var entry = TryCreateEntry(option, item.Group, groupName, item.ModAbbreviation, formatBool); var entry = TryCreateEntry(
option,
item.Group,
groupName,
item.ModAbbreviation,
modSearchTerms,
formatBool);
if (entry != null) if (entry != null)
{ {
entries.Add(entry); entries.Add(entry);
@@ -71,7 +88,7 @@ internal static class GuideOptionPages
if (entries.Count > 0) if (entries.Count > 0)
{ {
pages.Add(new GuideOptionPage(item.Group, item.ModAbbreviation, entries)); pages.Add(new GuideOptionPage(item.Group, item.ModAbbreviation, modSearchTerms, entries));
} }
} }
@@ -98,7 +115,21 @@ internal static class GuideOptionPages
} }
const StringComparison cmp = StringComparison.OrdinalIgnoreCase; const StringComparison cmp = StringComparison.OrdinalIgnoreCase;
return pages var pageList = pages.ToList();
var normalizedQuery = NormalizeSearchText(query);
var matchingModPages = normalizedQuery.Length < 3
? Array.Empty<GuideOptionPage>()
: pageList
.Where(page => page.ModSearchTerms.Any(term =>
NormalizeSearchText(term).Contains(normalizedQuery, StringComparison.Ordinal)))
.ToArray();
if (matchingModPages.Length > 0)
{
return matchingModPages.SelectMany(page => page.Entries).ToList();
}
return pageList
.SelectMany(page => page.Entries .SelectMany(page => page.Entries
.Select(entry => (Entry: entry, Rank: Rank(entry, query, cmp))) .Select(entry => (Entry: entry, Rank: Rank(entry, query, cmp)))
.Where(result => result.Rank < int.MaxValue) .Where(result => result.Rank < int.MaxValue)
@@ -107,6 +138,40 @@ internal static class GuideOptionPages
.ToList(); .ToList();
} }
private static IReadOnlyList<string> GetModSearchTerms(MiraPluginInfo plugin, AbstractOptionGroup group)
{
var terms = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
plugin.PluginId,
plugin.PluginInfo.Metadata.Name,
plugin.MiraPlugin.OptionsTitleText,
plugin.MiraPlugin.ParentLocaleId,
plugin.MiraPlugin.GetAbbreviatedModName(),
};
AddNamespace(terms, plugin.MiraPlugin.GetType());
AddNamespace(terms, group.GetType());
foreach (var option in group.Options)
{
AddNamespace(terms, option.GetType());
}
return terms.Where(term => !string.IsNullOrWhiteSpace(term)).ToArray();
}
private static void AddNamespace(ISet<string> terms, Type type)
{
if (!string.IsNullOrWhiteSpace(type.Namespace))
{
terms.Add(type.Namespace);
}
}
private static string NormalizeSearchText(string value)
{
return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
}
private static int Rank(GuideOptionEntry entry, string query, StringComparison cmp) private static int Rank(GuideOptionEntry entry, string query, StringComparison cmp)
{ {
if (entry.Title.Equals(query, cmp)) if (entry.Title.Equals(query, cmp))
@@ -173,13 +238,14 @@ internal static class GuideOptionPages
AbstractOptionGroup group, AbstractOptionGroup group,
string groupName, string groupName,
string modAbbreviation, string modAbbreviation,
IReadOnlyList<string> modSearchTerms,
Func<bool, string> formatBool) Func<bool, string> formatBool)
{ {
try try
{ {
var title = TranslationController.Instance.GetString(option.StringName); var title = TranslationController.Instance.GetString(option.StringName);
var value = FormatValue(option, formatBool); var value = FormatValue(option, formatBool);
return new GuideOptionEntry(title, value, group, groupName, modAbbreviation); return new GuideOptionEntry(title, value, group, groupName, modAbbreviation, modSearchTerms);
} }
catch (Exception e) catch (Exception e)
{ {