Perl Module: String::FuzzyMatch
I often find myself writing some small tool where I need to select a file
or other string. I could do so from the command line, adding some mechanism
to add command line completion, but most of the time, I reach for
fzf. The program takes a list of strings
from STDIN. It displays them as a list and allows me to select an item with
the cursor keys, and to filter the list by typing any sequence of characters.
The searching is fuzzy. It filters the list by any string that contains the
typed characters in sequence.For the example below, I'm listing files in a
directory. There is a file named with an umlaut, hätte.test.

When filtering the list, fzf will ignore
any diacritics in the filename, so typing ha filters the list down to
Changes and hätte.test.

Typing an actual umlaut there respects the diacritics and thus filters the
list immediately down to hätte.test.

In other situations, I can't readily shell out to fzf. Maybe because it is
in a web context or somewhere where I don't want to install fzf. For that
situation, I wrote (and now released)
String::FuzzyMatch. The module
provides a class where you can do such fuzzy filtering and highlighting
on your strings.
my $filter = String::FuzzyFind->new(
highlight_start => '[',
highlight_end => ']',
);
$filter->filter( 'ab', ['aab','abc','acb','cba','aaa', 'abab'] );
# ['aab','abc','acb','abab' ]
# HTML highlighting
my $html = String::FuzzyFind->new(
highlight_cb => sub( $match ) {
return join '',
'<highlight>',
html_escape($match),
'</highlight>',
};
);
$html->highlight( 'ab', 'Now Playing: äbändön' );
# 'Now Playing: <highlight>äb</highlight>'
$html->highlight( 'r&d', 'Welcome to R & D' );
# 'Welcome to <highlight>R</highlight> <highlight>&</highlight> <highlight>D</highlight>'
This approach is quite convenient, because it allows me to have both, a clicky menu when I'm working on a touch-enabled device, and some quick-access text entry box where I can type in a short code that matches whatever rare letters there are in the menu to select an option.
Writing the code was a fun exercise. The nice people at Perlmonks pointed me towards the appropirate Unicode properties to match or remove respectively. Then came a quick reminder about NFD, NFC and how I need consistency in my test suite and my code about when I'm returning what. In the end, I settled on accepting any encoding but converting and returning the original code while filtering a list and returning NFD when highlighting a string.