Move UsedLetters with RankedMatch
This commit is contained in:
parent
15b241b942
commit
c756f8f124
|
@ -6,6 +6,30 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
UsedLetters used_letters(StringView str)
|
||||||
|
{
|
||||||
|
UsedLetters res = 0;
|
||||||
|
for (auto c : str)
|
||||||
|
{
|
||||||
|
if (c >= 'a' and c <= 'z')
|
||||||
|
res |= 1uL << (c - 'a');
|
||||||
|
else if (c >= 'A' and c <= 'Z')
|
||||||
|
res |= 1uL << (c - 'A' + 26);
|
||||||
|
else if (c == '_')
|
||||||
|
res |= 1uL << 53;
|
||||||
|
else if (c == '-')
|
||||||
|
res |= 1uL << 54;
|
||||||
|
else
|
||||||
|
res |= 1uL << 63;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matches(UsedLetters query, UsedLetters letters)
|
||||||
|
{
|
||||||
|
return (query & letters) == query;
|
||||||
|
}
|
||||||
|
|
||||||
using Utf8It = utf8::iterator<const char*>;
|
using Utf8It = utf8::iterator<const char*>;
|
||||||
|
|
||||||
static int count_word_boundaries_match(StringView candidate, StringView query)
|
static int count_word_boundaries_match(StringView candidate, StringView query)
|
||||||
|
@ -68,26 +92,36 @@ static bool subsequence_match_smart_case(StringView str, StringView subseq, int&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RankedMatch::RankedMatch(StringView candidate, StringView query)
|
template<typename TestFunc>
|
||||||
|
RankedMatch::RankedMatch(StringView candidate, StringView query, TestFunc func)
|
||||||
{
|
{
|
||||||
if (candidate.empty() or query.length() > candidate.length())
|
if (candidate.empty() or query.length() > candidate.length())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (query.empty())
|
if (query.empty())
|
||||||
|
m_candidate = candidate;
|
||||||
|
else if (func() and subsequence_match_smart_case(candidate, query, m_match_index_sum))
|
||||||
{
|
{
|
||||||
m_candidate = candidate;
|
m_candidate = candidate;
|
||||||
return;
|
|
||||||
|
m_first_char_match = smartcase_eq(query[0], candidate[0]);
|
||||||
|
m_word_boundary_match_count = count_word_boundaries_match(candidate, query);
|
||||||
|
m_only_word_boundary = m_word_boundary_match_count == query.length();
|
||||||
|
m_prefix = std::equal(query.begin(), query.end(), candidate.begin(), smartcase_eq);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (not subsequence_match_smart_case(candidate, query, m_match_index_sum))
|
RankedMatch::RankedMatch(StringView candidate, UsedLetters candidate_letters,
|
||||||
return;
|
StringView query, UsedLetters query_letters)
|
||||||
|
: RankedMatch{candidate, query, [&] {
|
||||||
|
return matches(to_lower(query_letters), to_lower(candidate_letters)) and
|
||||||
|
matches(query_letters & upper_mask, candidate_letters & upper_mask);
|
||||||
|
}} {}
|
||||||
|
|
||||||
m_candidate = candidate;
|
|
||||||
|
|
||||||
m_first_char_match = smartcase_eq(query[0], candidate[0]);
|
RankedMatch::RankedMatch(StringView candidate, StringView query)
|
||||||
m_word_boundary_match_count = count_word_boundaries_match(candidate, query);
|
: RankedMatch{candidate, query, [] { return true; }}
|
||||||
m_only_word_boundary = m_word_boundary_match_count == query.length();
|
{
|
||||||
m_prefix = std::equal(query.begin(), query.end(), candidate.begin(), smartcase_eq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RankedMatch::operator<(const RankedMatch& other) const
|
bool RankedMatch::operator<(const RankedMatch& other) const
|
||||||
|
@ -131,4 +165,9 @@ UnitTest test_ranked_match{[] {
|
||||||
kak_assert(count_word_boundaries_match("countWordBoundariesMatch", "cWBM") == 4);
|
kak_assert(count_word_boundaries_match("countWordBoundariesMatch", "cWBM") == 4);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
UnitTest test_used_letters{[]()
|
||||||
|
{
|
||||||
|
kak_assert(used_letters("abcd") == to_lower(used_letters("abcdABCD")));
|
||||||
|
}};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,21 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using UsedLetters = uint64_t;
|
||||||
|
UsedLetters used_letters(StringView str);
|
||||||
|
|
||||||
|
constexpr UsedLetters upper_mask = 0xFFFFFFC000000;
|
||||||
|
|
||||||
|
inline UsedLetters to_lower(UsedLetters letters)
|
||||||
|
{
|
||||||
|
return ((letters & upper_mask) >> 26) | (letters & (~upper_mask));
|
||||||
|
}
|
||||||
|
|
||||||
struct RankedMatch
|
struct RankedMatch
|
||||||
{
|
{
|
||||||
RankedMatch(StringView candidate, StringView query);
|
RankedMatch(StringView candidate, StringView query);
|
||||||
|
RankedMatch(StringView candidate, UsedLetters candidate_letters,
|
||||||
|
StringView query, UsedLetters query_letters);
|
||||||
|
|
||||||
const StringView& candidate() const { return m_candidate; }
|
const StringView& candidate() const { return m_candidate; }
|
||||||
bool operator<(const RankedMatch& other) const;
|
bool operator<(const RankedMatch& other) const;
|
||||||
|
@ -17,6 +29,9 @@ struct RankedMatch
|
||||||
explicit operator bool() const { return not m_candidate.empty(); }
|
explicit operator bool() const { return not m_candidate.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<typename TestFunc>
|
||||||
|
RankedMatch(StringView candidate, StringView query, TestFunc test);
|
||||||
|
|
||||||
StringView m_candidate;
|
StringView m_candidate;
|
||||||
bool m_first_char_match = false;
|
bool m_first_char_match = false;
|
||||||
bool m_prefix = false;
|
bool m_prefix = false;
|
||||||
|
|
|
@ -8,35 +8,8 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
UsedLetters used_letters(StringView str)
|
|
||||||
{
|
|
||||||
UsedLetters res;
|
|
||||||
for (auto c : str)
|
|
||||||
{
|
|
||||||
if (c >= 'a' and c <= 'z')
|
|
||||||
res.set(c - 'a');
|
|
||||||
else if (c >= 'A' and c <= 'Z')
|
|
||||||
res.set(c - 'A' + 26);
|
|
||||||
else if (c == '_')
|
|
||||||
res.set(53);
|
|
||||||
else if (c == '-')
|
|
||||||
res.set(54);
|
|
||||||
else
|
|
||||||
res.set(63);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr UsedLetters upper_mask = 0xFFFFFFC000000;
|
|
||||||
|
|
||||||
UsedLetters to_lower(UsedLetters letters)
|
|
||||||
{
|
|
||||||
return ((letters & upper_mask) >> 26) | (letters & (~upper_mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
using WordList = Vector<StringView>;
|
using WordList = Vector<StringView>;
|
||||||
|
|
||||||
|
|
||||||
static WordList get_words(StringView content)
|
static WordList get_words(StringView content)
|
||||||
{
|
{
|
||||||
WordList res;
|
WordList res;
|
||||||
|
@ -155,11 +128,6 @@ int WordDB::get_word_occurences(StringView word) const
|
||||||
|
|
||||||
RankedMatchList WordDB::find_matching(StringView query)
|
RankedMatchList WordDB::find_matching(StringView query)
|
||||||
{
|
{
|
||||||
auto matches = [](UsedLetters query, UsedLetters letters)
|
|
||||||
{
|
|
||||||
return (query & letters) == query;
|
|
||||||
};
|
|
||||||
|
|
||||||
update_db();
|
update_db();
|
||||||
const UsedLetters letters = used_letters(query);
|
const UsedLetters letters = used_letters(query);
|
||||||
RankedMatchList res;
|
RankedMatchList res;
|
||||||
|
@ -171,12 +139,7 @@ RankedMatchList WordDB::find_matching(StringView query)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UsedLetters word_letters = word.second.letters;
|
if (RankedMatch match{word.first, word.second.letters, query, letters})
|
||||||
if (not matches(to_lower(letters), to_lower(word_letters)) or
|
|
||||||
not matches(letters & upper_mask, word_letters & upper_mask))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (RankedMatch match{word.first, query})
|
|
||||||
res.push_back(match);
|
res.push_back(match);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,9 +182,4 @@ UnitTest test_word_db{[]()
|
||||||
kak_assert(eq(res, WordList{ "allo" COMMA "mutch" COMMA "retchou" COMMA "tchou" }));
|
kak_assert(eq(res, WordList{ "allo" COMMA "mutch" COMMA "retchou" COMMA "tchou" }));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
UnitTest test_used_letters{[]()
|
|
||||||
{
|
|
||||||
kak_assert(used_letters("abcd") == to_lower(used_letters("abcdABCD")));
|
|
||||||
}};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,9 @@
|
||||||
#include "vector.hh"
|
#include "vector.hh"
|
||||||
#include "ranked_match.hh"
|
#include "ranked_match.hh"
|
||||||
|
|
||||||
#include <bitset>
|
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
using UsedLetters = std::bitset<64>;
|
|
||||||
UsedLetters used_letters(StringView str);
|
|
||||||
|
|
||||||
using RankedMatchList = Vector<RankedMatch>;
|
using RankedMatchList = Vector<RankedMatch>;
|
||||||
|
|
||||||
// maintain a database of words available in a buffer
|
// maintain a database of words available in a buffer
|
||||||
|
|
Loading…
Reference in New Issue
Block a user