Extract a for_n_best algorithm from completion function
Provide the heap based n-best algorithm through a nice interface.
This commit is contained in:
parent
c2759ac526
commit
e207bd30d4
|
@ -993,17 +993,15 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
|
|||
}
|
||||
|
||||
constexpr size_t max_count = 100;
|
||||
// Gather best max_count matches
|
||||
auto greater = [](auto& lhs, auto& rhs) { return rhs < lhs; };
|
||||
auto first = matches.begin(), last = matches.end();
|
||||
std::make_heap(first, last, greater);
|
||||
CandidateList res;
|
||||
while (res.size() < max_count and first != last)
|
||||
{
|
||||
if (res.empty() or res.back() != first->candidate())
|
||||
res.push_back(first->candidate().str());
|
||||
std::pop_heap(first, last--, greater);
|
||||
}
|
||||
// Gather best max_count matches
|
||||
for_n_best(matches, max_count, [](auto& lhs, auto& rhs) { return rhs < lhs; },
|
||||
[&] (RankedMatch& m) {
|
||||
if (not res.empty() and res.back() == m.candidate())
|
||||
return false;
|
||||
res.push_back(m.candidate().str());
|
||||
return true;
|
||||
});
|
||||
|
||||
return Completions{ 0_byte, pos_in_token, std::move(res) };
|
||||
};
|
||||
|
|
|
@ -177,30 +177,27 @@ InsertCompletion complete_word(const SelectionList& sels,
|
|||
|
||||
constexpr size_t max_count = 100;
|
||||
// Gather best max_count matches
|
||||
auto greater = [](auto& lhs, auto& rhs) { return rhs < lhs; };
|
||||
auto first = matches.begin(), last = matches.end();
|
||||
std::make_heap(first, last, greater);
|
||||
InsertCompletion::CandidateList candidates;
|
||||
candidates.reserve(std::min(matches.size(), max_count));
|
||||
while (candidates.size() < max_count and first != last)
|
||||
{
|
||||
if (candidates.empty() or candidates.back().completion != first->candidate())
|
||||
{
|
||||
DisplayLine menu_entry;
|
||||
if (other_buffers && first->buffer)
|
||||
{
|
||||
const auto pad_len = longest + 1 - first->candidate().char_length();
|
||||
menu_entry.push_back(first->candidate().str());
|
||||
menu_entry.push_back(String{' ', pad_len});
|
||||
menu_entry.push_back({ first->buffer->display_name(), faces["MenuInfo"] });
|
||||
}
|
||||
else
|
||||
menu_entry.push_back(first->candidate().str());
|
||||
|
||||
candidates.push_back({first->candidate().str(), "", std::move(menu_entry)});
|
||||
for_n_best(matches, max_count, [](auto& lhs, auto& rhs) { return rhs < lhs; },
|
||||
[&](RankedMatchAndBuffer& m) {
|
||||
if (not candidates.empty() and candidates.back().completion == m.candidate())
|
||||
return false;
|
||||
DisplayLine menu_entry;
|
||||
if (other_buffers && m.buffer)
|
||||
{
|
||||
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(), faces["MenuInfo"] });
|
||||
}
|
||||
std::pop_heap(first, last--, greater);
|
||||
}
|
||||
else
|
||||
menu_entry.push_back(m.candidate().str());
|
||||
|
||||
candidates.push_back({m.candidate().str(), "", std::move(menu_entry)});
|
||||
return true;
|
||||
});
|
||||
|
||||
return { std::move(candidates), word_begin, cursor_pos, buffer.timestamp() };
|
||||
}
|
||||
|
|
|
@ -364,6 +364,20 @@ Init accumulate(Range&& c, Init&& init, BinOp&& op)
|
|||
return std::accumulate(begin(c), end(c), init, op);
|
||||
}
|
||||
|
||||
template<typename Range, typename Compare, typename Func>
|
||||
void for_n_best(Range&& c, size_t count, Compare&& compare, Func&& func)
|
||||
{
|
||||
using std::begin; using std::end;
|
||||
auto b = begin(c), e = end(c);
|
||||
std::make_heap(b, e, compare);
|
||||
while (count > 0 and b != e)
|
||||
{
|
||||
if (func(*b))
|
||||
--count;
|
||||
std::pop_heap(b, e--, compare);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
auto gather()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user