catalog: Display commands that begin with selection first

When selecting `FORE` in the catalog, show `Foreground` first, before
all other commands that contain `Foreground` (there are many settings
with that name).

Fixes: #1106

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
Christophe de Dinechin 2024-08-13 17:41:12 +02:00
parent d7547676d8
commit de78d5f572
2 changed files with 30 additions and 17 deletions

View file

@ -165,18 +165,19 @@ static void initialize_sorted_ids()
#endif // DEOPTIMIZE_CATALOG
static bool matches(utf8 start, size_t size, utf8 name)
static uint matches(utf8 start, size_t size, utf8 name)
// ----------------------------------------------------------------------------
// Check if what was typed matches the name
// ----------------------------------------------------------------------------
{
size_t len = strlen(cstring(name));
bool found = false;
uint found = 0;
for (uint o = 0; !found && o + size <= len; o++)
{
found = true;
found = o+1;
for (uint i = 0; found && i < size; i++)
found = tolower(start[i]) == tolower(name[i + o]);
if (tolower(start[i]) != tolower(name[i + o]))
found = 0;
}
return found;
}
@ -221,14 +222,26 @@ void Catalog::list_commands(info &mi)
if (sorted_ids)
{
for (size_t i = 0; i < sorted_ids_count; i++)
for (uint pass = 0; pass < uint(filter) + 1; pass++)
{
uint16_t j = sorted_ids[i];
auto &s = object::spellings[j];
id ty = s.type;
if (cstring name = s.name)
if (!filter || matches(start, size, utf8(name)))
menu::items(mi, name, command::static_object(ty));
for (size_t i = 0; i < sorted_ids_count; i++)
{
uint16_t j = sorted_ids[i];
auto &s = object::spellings[j];
id ty = s.type;
if (cstring name = s.name)
{
uint ok = !filter;
if (!ok)
{
ok = matches(start, size, utf8(name));
if (ok)
ok = pass ? ok != 1 : ok == 1;
}
if (ok)
menu::items(mi, name, command::static_object(ty));
}
}
}
}
else

View file

@ -6135,15 +6135,15 @@ void tests::catalog_test()
.test(CLEAR, RSHIFT, RUNSTOP).editor("{}")
.test(ALPHA, A).editor("{A}")
.test(ADD).editor("{A}")
.test(F1).editor("{ %Change }");
.test(F1).editor("{ abs }");
step("Finding functions from inside")
.test(B).editor("{ %Change B}")
.test(F1).editor("{ %Change abs }");
.test(B).editor("{ abs B}")
.test(F1).editor("{ abs Background }");
step("Finding functions with middle characters")
.test(B, U).editor("{ %Change abs BU}")
.test(F1).editor("{ %Change abs Debug }");
.test(B, U).editor("{ abs Background BU}")
.test(F1).editor("{ abs Background Debug }");
step("Catalog with nothing entered")
.test(F6, F3).editor("{ %Change abs Debug cosh⁻¹ }");
.test(F6, F3).editor("{ abs Background Debug cosh⁻¹ }");
step("Test the default menu")
.test(CLEAR, EXIT, A, RSHIFT, RUNSTOP).editor("{}")