summaryrefslogtreecommitdiff
path: root/src/ranked_match.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2023-11-15 12:26:27 +1100
committerMaxime Coste <mawww@kakoune.org>2023-11-15 12:27:48 +1100
commit4a1a3ee06e9df1af5b2b6f6627200f92e64fe515 (patch)
treede2ca3289ed6629d63a9ce8d3cf26ef1f7713691 /src/ranked_match.cc
parent11f0ace9b6bf7cf618a42de7e37d9608d2d86d99 (diff)
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.
Diffstat (limited to 'src/ranked_match.cc')
-rw-r--r--src/ranked_match.cc17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/ranked_match.cc b/src/ranked_match.cc
index f48b7e0f..dc2ef5a1 100644
--- a/src/ranked_match.cc
+++ b/src/ranked_match.cc
@@ -135,8 +135,14 @@ RankedMatch::RankedMatch(StringView candidate, StringView query, TestFunc func)
if (res->single_word)
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(),
query.begin(), query.end(), smartcase_eq);
@@ -190,8 +196,8 @@ bool RankedMatch::operator<(const RankedMatch& other) const
if (diff != Flags::None)
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
- // other words boundaries into account.
+ // If we are SingleWord, we dont want to take word boundaries from other
+ // words into account.
if (not (m_flags & (Flags::Prefix | Flags::SingleWord)) and
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("expresins", "expresions", "expressionism's"));
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{[]()