summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-10-27 21:25:18 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-10-27 21:25:18 +0000
commit89d22f3335dfa471189f4925ec58d9b658a269ae (patch)
treec643a7ff05cba6e3d66c4d93b139cb78ae083b25
parent2eba789610c71b23dc7a32107ee6350cd810a9cf (diff)
Move more logic into RankedMatch
-rw-r--r--src/insert_completer.cc37
-rw-r--r--src/ranked_match.cc27
-rw-r--r--src/ranked_match.hh16
-rw-r--r--src/word_db.cc11
4 files changed, 57 insertions, 34 deletions
diff --git a/src/insert_completer.cc b/src/insert_completer.cc
index a4ce0ba6..02b88856 100644
--- a/src/insert_completer.cc
+++ b/src/insert_completer.cc
@@ -95,11 +95,13 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
struct RankedMatchAndBuffer : RankedMatch
{
- RankedMatchAndBuffer(StringView w, int r = 0, const Buffer* b = nullptr)
- : RankedMatch{w, r}, buffer{b} {}
+ RankedMatchAndBuffer(const RankedMatch& m, const Buffer* b = nullptr)
+ : RankedMatch{m}, buffer{b} {}
- bool operator==(const RankedMatchAndBuffer& other) const { return word == other.word; }
- bool operator<(const RankedMatchAndBuffer& other) const { return rank > other.rank; }
+ bool operator==(StringView other) const { return candidate() == other; }
+
+ bool operator==(const RankedMatchAndBuffer& other) const { return RankedMatch::operator==(other); }
+ bool operator<(const RankedMatchAndBuffer& other) const { return RankedMatch::operator<(other);; }
const Buffer* buffer;
};
@@ -109,7 +111,7 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
auto& word_db = get_word_db(buf);
auto bufmatches = word_db.find_matching(prefix);
for (auto& m : bufmatches)
- matches.push_back({ m.word, m.rank, &buf });
+ matches.push_back({ m, &buf });
};
add_matches(buffer);
@@ -127,23 +129,12 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
}
}
unordered_erase(matches, StringView{prefix});
- // Sort by word, favoring lowercase
- std::sort(matches.begin(), matches.end(),
- [](const RankedMatchAndBuffer& lhs, const RankedMatchAndBuffer& rhs) {
- return std::lexicographical_compare(
- lhs.word.begin(), lhs.word.end(), rhs.word.begin(), rhs.word.end(),
- [](char a, char b) {
- const bool low_a = islower(a), low_b = islower(b);
- return low_a == low_b ? a < b : low_a;
- });
- });
+ std::sort(matches.begin(), matches.end());
matches.erase(std::unique(matches.begin(), matches.end()), matches.end());
- // Stable sort by rank to preserve by word sorting
- std::stable_sort(matches.begin(), matches.end());
const auto longest = std::accumulate(matches.begin(), matches.end(), 0_char,
[](const CharCount& lhs, const RankedMatchAndBuffer& rhs)
- { return std::max(lhs, rhs.word.char_length()); });
+ { return std::max(lhs, rhs.candidate().char_length()); });
InsertCompletion::CandidateList candidates;
candidates.reserve(matches.size());
@@ -152,17 +143,15 @@ InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
DisplayLine menu_entry;
if (m.buffer)
{
- const auto pad_len = longest + 1 - m.word.char_length();
- menu_entry.push_back(m.word.str());
+ const auto pad_len = longest + 1 - m.candidate().char_length();
+ menu_entry.push_back(m.candidate().str());
menu_entry.push_back(String{' ', pad_len});
menu_entry.push_back({ m.buffer->display_name(), get_face("MenuInfo") });
}
else
- menu_entry.push_back(m.word.str());
-
- menu_entry.push_back({ " " + to_string(m.rank), get_face("cyan") });
+ menu_entry.push_back(m.candidate().str());
- candidates.push_back({m.word.str(), "", std::move(menu_entry)});
+ candidates.push_back({m.candidate().str(), "", std::move(menu_entry)});
}
return { begin.coord(), cursor_pos, std::move(candidates), buffer.timestamp() };
diff --git a/src/ranked_match.cc b/src/ranked_match.cc
index 0063b8ae..03cb2fcd 100644
--- a/src/ranked_match.cc
+++ b/src/ranked_match.cc
@@ -3,7 +3,7 @@
namespace Kakoune
{
-int match_rank(StringView candidate, StringView query)
+static bool match_rank(StringView candidate, StringView query)
{
int rank = 0;
auto it = candidate.begin();
@@ -37,4 +37,29 @@ int match_rank(StringView candidate, StringView query)
return rank;
}
+RankedMatch::RankedMatch(StringView candidate, StringView query)
+{
+ if (candidate.empty() or query.empty())
+ {
+ m_candidate = candidate;
+ return;
+ }
+
+ m_match_rank = match_rank(candidate, query);
+}
+
+bool RankedMatch::operator<(const RankedMatch& other) const
+{
+ if (m_match_rank == other.m_match_rank)
+ return std::lexicographical_compare(
+ m_candidate.begin(), m_candidate.end(),
+ other.m_candidate.begin(), other.m_candidate.end(),
+ [](char a, char b) {
+ const bool low_a = islower(a), low_b = islower(b);
+ return low_a == low_b ? a < b : low_a;
+ });
+
+ return m_match_rank < other.m_match_rank;
+}
+
}
diff --git a/src/ranked_match.hh b/src/ranked_match.hh
index 2e248dc1..d6367453 100644
--- a/src/ranked_match.hh
+++ b/src/ranked_match.hh
@@ -9,12 +9,20 @@ namespace Kakoune
struct RankedMatch
{
- StringView word;
- int rank;
+ RankedMatch(StringView candidate, StringView query);
+
+ const StringView& candidate() const { return m_candidate; }
+ bool operator<(const RankedMatch& other) const;
+ bool operator==(const RankedMatch& other) const { return m_candidate == other.m_candidate; }
+
+ explicit operator bool() const { return not m_candidate.empty(); }
+
+private:
+ StringView m_candidate;
+ int m_match_rank = 0;
};
-using RankedMatchList = Vector<RankedMatch>;
-int match_rank(StringView candidate, StringView query);
+using RankedMatchList = Vector<RankedMatch>;
}
diff --git a/src/word_db.cc b/src/word_db.cc
index 80b59f0c..147287b5 100644
--- a/src/word_db.cc
+++ b/src/word_db.cc
@@ -160,7 +160,7 @@ RankedMatchList WordDB::find_matching(StringView query)
{
if (query.empty())
{
- res.push_back({word.first, 1 });
+ res.push_back(RankedMatch{word.first, query});
continue;
}
@@ -168,8 +168,9 @@ RankedMatchList WordDB::find_matching(StringView query)
if (not matches(to_lower(letters), to_lower(word_letters)) or
not matches(letters & upper_mask, word_letters & upper_mask))
continue;
- if (int rank = match_rank(word.first, query))
- res.push_back({ word.first, rank });
+
+ if (RankedMatch match{word.first, query})
+ res.push_back(match);
}
return res;
@@ -178,14 +179,14 @@ RankedMatchList WordDB::find_matching(StringView query)
UnitTest test_word_db{[]()
{
auto cmp_words = [](const RankedMatch& lhs, const RankedMatch& rhs) {
- return lhs.word < rhs.word;
+ return lhs.candidate() < rhs.candidate();
};
auto eq = [](ArrayView<const RankedMatch> lhs, const WordList& rhs) {
return lhs.size() == rhs.size() and
std::equal(lhs.begin(), lhs.end(), rhs.begin(),
[](const RankedMatch& lhs, const StringView& rhs) {
- return lhs.word == rhs;
+ return lhs.candidate() == rhs;
});
};