Extract WordDB::RankedWord as RankedMatch in its own file

This commit is contained in:
Maxime Coste 2015-10-22 19:49:08 +01:00
parent 019b3235b0
commit c77cb7c777
5 changed files with 76 additions and 55 deletions

View File

@ -93,17 +93,17 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
String current_word{begin, end}; String current_word{begin, end};
struct RankedWordAndBuffer : WordDB::RankedWord struct RankedMatchAndBuffer : RankedMatch
{ {
RankedWordAndBuffer(StringView w, int r = 0, const Buffer* b = nullptr) RankedMatchAndBuffer(StringView w, int r = 0, const Buffer* b = nullptr)
: WordDB::RankedWord{w, r}, buffer{b} {} : RankedMatch{w, r}, buffer{b} {}
bool operator==(const RankedWordAndBuffer& other) const { return word == other.word; } bool operator==(const RankedMatchAndBuffer& other) const { return word == other.word; }
bool operator<(const RankedWordAndBuffer& other) const { return rank > other.rank; } bool operator<(const RankedMatchAndBuffer& other) const { return rank > other.rank; }
const Buffer* buffer; const Buffer* buffer;
}; };
Vector<RankedWordAndBuffer> matches; Vector<RankedMatchAndBuffer> matches;
auto add_matches = [&](const Buffer& buf) { auto add_matches = [&](const Buffer& buf) {
auto& word_db = get_word_db(buf); auto& word_db = get_word_db(buf);
@ -129,7 +129,7 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
unordered_erase(matches, StringView{prefix}); unordered_erase(matches, StringView{prefix});
// Sort by word, favoring lowercase // Sort by word, favoring lowercase
std::sort(matches.begin(), matches.end(), std::sort(matches.begin(), matches.end(),
[](const RankedWordAndBuffer& lhs, const RankedWordAndBuffer& rhs) { [](const RankedMatchAndBuffer& lhs, const RankedMatchAndBuffer& rhs) {
return std::lexicographical_compare( return std::lexicographical_compare(
lhs.word.begin(), lhs.word.end(), rhs.word.begin(), rhs.word.end(), lhs.word.begin(), lhs.word.end(), rhs.word.begin(), rhs.word.end(),
[](char a, char b) { [](char a, char b) {
@ -142,7 +142,7 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
std::stable_sort(matches.begin(), matches.end()); std::stable_sort(matches.begin(), matches.end());
const auto longest = std::accumulate(matches.begin(), matches.end(), 0_char, const auto longest = std::accumulate(matches.begin(), matches.end(), 0_char,
[](const CharCount& lhs, const RankedWordAndBuffer& rhs) [](const CharCount& lhs, const RankedMatchAndBuffer& rhs)
{ return std::max(lhs, rhs.word.char_length()); }); { return std::max(lhs, rhs.word.char_length()); });
InsertCompletion::CandidateList candidates; InsertCompletion::CandidateList candidates;

40
src/ranked_match.cc Normal file
View File

@ -0,0 +1,40 @@
#include "ranked_match.hh"
namespace Kakoune
{
int match_rank(StringView candidate, StringView query)
{
int rank = 0;
auto it = candidate.begin();
char prev = 0;
for (auto c : query)
{
if (it == candidate.end())
return 0;
const bool islow = islower(c);
auto eq_c = [islow, c](char ch) { return islow ? tolower(ch) == c : ch == c; };
if (eq_c(*it)) // improve rank on contiguous
++rank;
while (!eq_c(*it))
{
prev = *it;
if (++it == candidate.end())
return 0;
}
// Improve rank on word boundaries
if (prev == 0 or prev == '_' or
(islower(prev) and isupper(*it)))
rank += 5;
prev = c;
++rank;
++it;
}
return rank;
}
}

21
src/ranked_match.hh Normal file
View File

@ -0,0 +1,21 @@
#ifndef ranked_match_hh_INCLUDED
#define ranked_match_hh_INCLUDED
#include "string.hh"
#include "vector.hh"
namespace Kakoune
{
struct RankedMatch
{
StringView word;
int rank;
};
using RankedMatchList = Vector<RankedMatch>;
int match_rank(StringView candidate, StringView query);
}
#endif // ranked_match_hh_INCLUDED

View File

@ -146,42 +146,8 @@ int WordDB::get_word_occurences(StringView word) const
return 0; return 0;
} }
WordDB::RankedWordList WordDB::find_matching(StringView query) RankedMatchList WordDB::find_matching(StringView query)
{ {
auto match_rank = [](StringView candidate, StringView query)
{
int rank = 0;
auto it = candidate.begin();
char prev = 0;
for (auto c : query)
{
if (it == candidate.end())
return 0;
const bool islow = islower(c);
auto eq_c = [islow, c](char ch) { return islow ? tolower(ch) == c : ch == c; };
if (eq_c(*it)) // improve rank on contiguous
++rank;
while (!eq_c(*it))
{
prev = *it;
if (++it == candidate.end())
return 0;
}
// Improve rank on word boundaries
if (prev == 0 or prev == '_' or
(islower(prev) and isupper(*it)))
rank += 5;
prev = c;
++rank;
++it;
}
return rank;
};
auto matches = [](UsedLetters query, UsedLetters letters) auto matches = [](UsedLetters query, UsedLetters letters)
{ {
return (query & letters) == query; return (query & letters) == query;
@ -189,7 +155,7 @@ WordDB::RankedWordList WordDB::find_matching(StringView query)
update_db(); update_db();
const UsedLetters letters = used_letters(query); const UsedLetters letters = used_letters(query);
RankedWordList res; RankedMatchList res;
for (auto&& word : m_words) for (auto&& word : m_words)
{ {
if (query.empty()) if (query.empty())
@ -211,14 +177,14 @@ WordDB::RankedWordList WordDB::find_matching(StringView query)
UnitTest test_word_db{[]() UnitTest test_word_db{[]()
{ {
auto cmp_words = [](const WordDB::RankedWord& lhs, const WordDB::RankedWord& rhs) { auto cmp_words = [](const RankedMatch& lhs, const RankedMatch& rhs) {
return lhs.word < rhs.word; return lhs.word < rhs.word;
}; };
auto eq = [](ArrayView<const WordDB::RankedWord> lhs, const WordList& rhs) { auto eq = [](ArrayView<const RankedMatch> lhs, const WordList& rhs) {
return lhs.size() == rhs.size() and return lhs.size() == rhs.size() and
std::equal(lhs.begin(), lhs.end(), rhs.begin(), std::equal(lhs.begin(), lhs.end(), rhs.begin(),
[](const WordDB::RankedWord& lhs, const StringView& rhs) { [](const RankedMatch& lhs, const StringView& rhs) {
return lhs.word == rhs; return lhs.word == rhs;
}); });
}; };

View File

@ -5,6 +5,7 @@
#include "shared_string.hh" #include "shared_string.hh"
#include "unordered_map.hh" #include "unordered_map.hh"
#include "vector.hh" #include "vector.hh"
#include "ranked_match.hh"
#include <bitset> #include <bitset>
@ -22,14 +23,7 @@ public:
WordDB(const WordDB&) = delete; WordDB(const WordDB&) = delete;
WordDB(WordDB&&) = default; WordDB(WordDB&&) = default;
struct RankedWord RankedMatchList find_matching(StringView str);
{
StringView word;
int rank;
};
using RankedWordList = Vector<RankedWord>;
RankedWordList find_matching(StringView str);
int get_word_occurences(StringView word) const; int get_word_occurences(StringView word) const;
private: private: