diff options
| author | Maxime Coste <mawww@kakoune.org> | 2023-11-15 12:26:27 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2023-11-15 12:27:48 +1100 |
| commit | 4a1a3ee06e9df1af5b2b6f6627200f92e64fe515 (patch) | |
| tree | de2ca3289ed6629d63a9ce8d3cf26ef1f7713691 /src | |
| parent | 11f0ace9b6bf7cf618a42de7e37d9608d2d86d99 (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')
| -rw-r--r-- | src/ranked_match.cc | 17 | ||||
| -rw-r--r-- | src/ranked_match.hh | 10 |
2 files changed, 18 insertions, 9 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{[]() diff --git a/src/ranked_match.hh b/src/ranked_match.hh index 62d6b8f0..01afe9cd 100644 --- a/src/ranked_match.hh +++ b/src/ranked_match.hh @@ -39,11 +39,11 @@ private: { None = 0, // Order is important, the highest bit has precedence for comparison - FirstCharMatch = 1 << 0, - SingleWord = 1 << 1, - Contiguous = 1 << 2, - OnlyWordBoundary = 1 << 3, - Prefix = 1 << 4, + SingleWord = 1 << 0, + Contiguous = 1 << 1, + OnlyWordBoundary = 1 << 2, + Prefix = 1 << 3, + BaseName = 1 << 4, SmartFullMatch = 1 << 5, FullMatch = 1 << 6, }; |
