summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-03-25 20:35:57 +0000
committerMaxime Coste <frrrwww@gmail.com>2016-03-25 20:38:27 +0000
commitc756f8f12465265e95aaab215260c79a7034e429 (patch)
tree313f2a01671b260d10d891679048532b8f4fea68
parent15b241b9428d25123db4d8bd8cd977fb991735f6 (diff)
Move UsedLetters with RankedMatch
-rw-r--r--src/ranked_match.cc57
-rw-r--r--src/ranked_match.hh15
-rw-r--r--src/word_db.cc44
-rw-r--r--src/word_db.hh5
4 files changed, 64 insertions, 57 deletions
diff --git a/src/ranked_match.cc b/src/ranked_match.cc
index 91bd57d3..11c58045 100644
--- a/src/ranked_match.cc
+++ b/src/ranked_match.cc
@@ -6,6 +6,30 @@
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*>;
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;
}
-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())
return;
if (query.empty())
+ m_candidate = candidate;
+ else if (func() and subsequence_match_smart_case(candidate, query, m_match_index_sum))
{
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))
- return;
+RankedMatch::RankedMatch(StringView candidate, UsedLetters candidate_letters,
+ 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]);
- 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);
+RankedMatch::RankedMatch(StringView candidate, StringView query)
+ : RankedMatch{candidate, query, [] { return true; }}
+{
}
bool RankedMatch::operator<(const RankedMatch& other) const
@@ -131,4 +165,9 @@ UnitTest test_ranked_match{[] {
kak_assert(count_word_boundaries_match("countWordBoundariesMatch", "cWBM") == 4);
}};
+UnitTest test_used_letters{[]()
+{
+ kak_assert(used_letters("abcd") == to_lower(used_letters("abcdABCD")));
+}};
+
}
diff --git a/src/ranked_match.hh b/src/ranked_match.hh
index de03fd4c..0e0e49c4 100644
--- a/src/ranked_match.hh
+++ b/src/ranked_match.hh
@@ -6,9 +6,21 @@
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
{
RankedMatch(StringView candidate, StringView query);
+ RankedMatch(StringView candidate, UsedLetters candidate_letters,
+ StringView query, UsedLetters query_letters);
const StringView& candidate() const { return m_candidate; }
bool operator<(const RankedMatch& other) const;
@@ -17,6 +29,9 @@ struct RankedMatch
explicit operator bool() const { return not m_candidate.empty(); }
private:
+ template<typename TestFunc>
+ RankedMatch(StringView candidate, StringView query, TestFunc test);
+
StringView m_candidate;
bool m_first_char_match = false;
bool m_prefix = false;
diff --git a/src/word_db.cc b/src/word_db.cc
index ed54910a..65685a39 100644
--- a/src/word_db.cc
+++ b/src/word_db.cc
@@ -8,35 +8,8 @@
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>;
-
static WordList get_words(StringView content)
{
WordList res;
@@ -155,11 +128,6 @@ int WordDB::get_word_occurences(StringView word) const
RankedMatchList WordDB::find_matching(StringView query)
{
- auto matches = [](UsedLetters query, UsedLetters letters)
- {
- return (query & letters) == query;
- };
-
update_db();
const UsedLetters letters = used_letters(query);
RankedMatchList res;
@@ -171,12 +139,7 @@ RankedMatchList WordDB::find_matching(StringView query)
continue;
}
- UsedLetters word_letters = word.second.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})
+ if (RankedMatch match{word.first, word.second.letters, query, letters})
res.push_back(match);
}
@@ -219,9 +182,4 @@ UnitTest test_word_db{[]()
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")));
-}};
-
}
diff --git a/src/word_db.hh b/src/word_db.hh
index a4644b5b..3dcf455d 100644
--- a/src/word_db.hh
+++ b/src/word_db.hh
@@ -7,14 +7,9 @@
#include "vector.hh"
#include "ranked_match.hh"
-#include <bitset>
-
namespace Kakoune
{
-using UsedLetters = std::bitset<64>;
-UsedLetters used_letters(StringView str);
-
using RankedMatchList = Vector<RankedMatch>;
// maintain a database of words available in a buffer