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;
|
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;
|
CandidateList res;
|
||||||
while (res.size() < max_count and first != last)
|
// Gather best max_count matches
|
||||||
{
|
for_n_best(matches, max_count, [](auto& lhs, auto& rhs) { return rhs < lhs; },
|
||||||
if (res.empty() or res.back() != first->candidate())
|
[&] (RankedMatch& m) {
|
||||||
res.push_back(first->candidate().str());
|
if (not res.empty() and res.back() == m.candidate())
|
||||||
std::pop_heap(first, last--, greater);
|
return false;
|
||||||
}
|
res.push_back(m.candidate().str());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
return Completions{ 0_byte, pos_in_token, std::move(res) };
|
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;
|
constexpr size_t max_count = 100;
|
||||||
// Gather best max_count matches
|
// 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;
|
InsertCompletion::CandidateList candidates;
|
||||||
candidates.reserve(std::min(matches.size(), max_count));
|
candidates.reserve(std::min(matches.size(), max_count));
|
||||||
while (candidates.size() < max_count and first != last)
|
|
||||||
{
|
for_n_best(matches, max_count, [](auto& lhs, auto& rhs) { return rhs < lhs; },
|
||||||
if (candidates.empty() or candidates.back().completion != first->candidate())
|
[&](RankedMatchAndBuffer& m) {
|
||||||
{
|
if (not candidates.empty() and candidates.back().completion == m.candidate())
|
||||||
|
return false;
|
||||||
DisplayLine menu_entry;
|
DisplayLine menu_entry;
|
||||||
if (other_buffers && first->buffer)
|
if (other_buffers && m.buffer)
|
||||||
{
|
{
|
||||||
const auto pad_len = longest + 1 - first->candidate().char_length();
|
const auto pad_len = longest + 1 - m.candidate().char_length();
|
||||||
menu_entry.push_back(first->candidate().str());
|
menu_entry.push_back(m.candidate().str());
|
||||||
menu_entry.push_back(String{' ', pad_len});
|
menu_entry.push_back(String{' ', pad_len});
|
||||||
menu_entry.push_back({ first->buffer->display_name(), faces["MenuInfo"] });
|
menu_entry.push_back({ m.buffer->display_name(), faces["MenuInfo"] });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
menu_entry.push_back(first->candidate().str());
|
menu_entry.push_back(m.candidate().str());
|
||||||
|
|
||||||
candidates.push_back({first->candidate().str(), "", std::move(menu_entry)});
|
candidates.push_back({m.candidate().str(), "", std::move(menu_entry)});
|
||||||
}
|
return true;
|
||||||
std::pop_heap(first, last--, greater);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return { std::move(candidates), word_begin, cursor_pos, buffer.timestamp() };
|
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);
|
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>
|
template<typename Container>
|
||||||
auto gather()
|
auto gather()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user