Refactor fuzzy matcher ranking further

Remove FirstCharMatch which does not impact any of the test cases
and explicitely detect paths by using a BaseName flag when we match
the basename of the path.
This commit is contained in:
Maxime Coste 2023-11-15 12:26:27 +11:00
parent 11f0ace9b6
commit 4a1a3ee06e
2 changed files with 18 additions and 9 deletions

View File

@ -135,8 +135,14 @@ RankedMatch::RankedMatch(StringView candidate, StringView query, TestFunc func)
if (res->single_word) if (res->single_word)
m_flags |= Flags::SingleWord; m_flags |= Flags::SingleWord;
if (smartcase_eq(candidate[0], query[0]))
m_flags |= Flags::FirstCharMatch; if (auto it = find(candidate | reverse(), '/').base();
it == candidate.begin() or subsequence_match_smart_case({it, candidate.end()}, query))
{
m_flags |= Flags::BaseName;
if (*it == query[0])
m_flags |= Flags::Prefix;
}
auto it = std::search(candidate.begin(), candidate.end(), auto it = std::search(candidate.begin(), candidate.end(),
query.begin(), query.end(), smartcase_eq); query.begin(), query.end(), smartcase_eq);
@ -190,8 +196,8 @@ bool RankedMatch::operator<(const RankedMatch& other) const
if (diff != Flags::None) if (diff != Flags::None)
return (int)(m_flags & diff) > (int)(other.m_flags & diff); return (int)(m_flags & diff) > (int)(other.m_flags & diff);
// If we are SingleWord, FirstCharMatch will do the job, and we dont want to take // If we are SingleWord, we dont want to take word boundaries from other
// other words boundaries into account. // words into account.
if (not (m_flags & (Flags::Prefix | Flags::SingleWord)) and if (not (m_flags & (Flags::Prefix | Flags::SingleWord)) and
m_word_boundary_match_count != other.m_word_boundary_match_count) m_word_boundary_match_count != other.m_word_boundary_match_count)
return m_word_boundary_match_count > other.m_word_boundary_match_count; return m_word_boundary_match_count > other.m_word_boundary_match_count;
@ -268,6 +274,9 @@ UnitTest test_ranked_match{[] {
kak_assert(preferred("", "a", "b")); kak_assert(preferred("", "a", "b"));
kak_assert(preferred("expresins", "expresions", "expressionism's")); kak_assert(preferred("expresins", "expresions", "expressionism's"));
kak_assert(preferred("foo_b", "foo/bar/foo_bar.baz", "test/test_foo_bar.baz")); kak_assert(preferred("foo_b", "foo/bar/foo_bar.baz", "test/test_foo_bar.baz"));
kak_assert(preferred("foo_b", "bar/bar_qux/foo_bar.baz", "foo/test_foo_bar.baz"));
kak_assert(preferred("foo_bar", "bar/foo_bar.baz", "foo_bar/qux.baz"));
kak_assert(preferred("fb", "foo_bar/", "foo.bar"));
}}; }};
UnitTest test_used_letters{[]() UnitTest test_used_letters{[]()

View File

@ -39,11 +39,11 @@ private:
{ {
None = 0, None = 0,
// Order is important, the highest bit has precedence for comparison // Order is important, the highest bit has precedence for comparison
FirstCharMatch = 1 << 0, SingleWord = 1 << 0,
SingleWord = 1 << 1, Contiguous = 1 << 1,
Contiguous = 1 << 2, OnlyWordBoundary = 1 << 2,
OnlyWordBoundary = 1 << 3, Prefix = 1 << 3,
Prefix = 1 << 4, BaseName = 1 << 4,
SmartFullMatch = 1 << 5, SmartFullMatch = 1 << 5,
FullMatch = 1 << 6, FullMatch = 1 << 6,
}; };