tildearrow / furnace

a multi-system chiptune tracker compatible with DefleMask modules
GNU General Public License v2.0
2.57k stars 206 forks source link

In command palette, sort matches by quality/exactness #2116

Closed alederer closed 1 week ago

alederer commented 1 month ago

This one sort of speaks for itself if you look at the images. But in brief, this change sorts the command palette results according to closeness to your search term.

After this change

Screenshot 2024-08-27 at 12 56 57 AM

A search for "int" yields "interpolate". Reasonable, that's the only one of the options that actually matches, the others are only fuzzy matches. This is a nice quick way of using the keyboard to get to the interpolate action.

Before this change

Screenshot 2024-08-27 at 12 57 47 AM

A search for "int" doesn't yield any results in the first page that even contain "int"!

Screenshot 2024-08-27 at 12 58 13 AM

Even if you expand the search to "inter", "interpolate" is still toward the bottom. This isn't very helpful.

Details

The specific "cost/score" function has two factors:

Further tie-breaking can be done (I experimented with counting characters after the end of the search term) but doesn't seem relevant (below a certain signal-to-noise-ratio, at a certain point the consistency of the original ordering becomes more valuable than seemingly random tie-breaks).

Caveats

I think this is definitely a good and simple change, but there is a weakness I noted in how I'm calculating the score -- it's using a greedy search, i.e. it considers the needle "found" in the haystack as soon as it encounters its first character, even if the full needle might be found perfectly intact later in the haystack. e.g. searching for "hello" in "hippohello" would be considered to have 5 chars interleaved in the search term ("ippoh"), when it would be more accurate to say it has a perfect match score of 0 because "hello" appears in it directly.

I haven't run into issues with this in practice, but I'd consider it an open area for future improvement.

alederer commented 1 month ago

i've converted to draft because i want to address the following:

alederer commented 1 month ago

[EDIT: including screenshot of what the command palette looks like with this PR, to avoid confusion]

image

updated the matching/sorting, added coloring, added shortcut display. i decided the utf8 stuff wasn't worth it, we don't support localized action names anyway, can revisit (i have some initial python code for converting that confusables.txt into a C function).

here's an example of the old greedy matcher vs. the new matcher:

greedy (my initial commit)

where are "move cursor up/down by one" when searching for "one"? their scores are poor because the matcher starts matching at the "o" in "move" and finishes it with the final "e" in "one", so it thinks it has a large distance (along the lines of levenshtein distance but just insertions) from "one".

greedy

non-greedy (new)

"move cursor up/down by one" are present near the top because the matcher correctly identifies a "tighter fit" is present than just taking the first fit

non_greedy