Try matching functions one by one when completing

Instead of running them all then deciding which to use.
This commit is contained in:
Maxime Coste 2015-05-26 18:38:48 +01:00
parent 3ca69c3852
commit 3bdc30e381

View File

@ -55,20 +55,22 @@ inline Completions offset_pos(Completions completion, ByteCount offset)
namespace detail namespace detail
{ {
template<typename Str, typename Func> template<typename Container, typename Func>
void do_matches(Str&& str, StringView prefix, void do_matches(Container&& container, StringView prefix,
CandidateList* res, Func match_func) CandidateList& res, Func match_func)
{ {
if (match_func(str, prefix)) for (auto&& elem : container)
res->push_back(str); if (match_func(elem, prefix))
res.push_back(elem);
} }
template<typename Str, typename Func, typename... Rest> template<typename Container, typename Func, typename... Rest>
void do_matches(Str&& str, StringView prefix, void do_matches(Container&& container, StringView prefix,
CandidateList* res, Func match_func, Rest... rest) CandidateList& res, Func match_func, Rest... rest)
{ {
do_matches(str, prefix, res, match_func); do_matches(container, prefix, res, match_func);
do_matches(str, prefix, res+1, rest...); if (res.empty())
do_matches(container, prefix, res, rest...);
} }
} }
@ -76,12 +78,9 @@ template<typename Container, typename... MatchFunc>
CandidateList complete(StringView prefix, ByteCount cursor_pos, CandidateList complete(StringView prefix, ByteCount cursor_pos,
const Container& container, MatchFunc... match_func) const Container& container, MatchFunc... match_func)
{ {
CandidateList res[sizeof...(match_func)]; CandidateList res;
auto real_prefix = prefix.substr(0, cursor_pos); detail::do_matches(container, prefix.substr(0, cursor_pos), res, match_func...);
for (const auto& elem : container) return res;
detail::do_matches(elem, real_prefix, res, match_func...);
auto it = find_if(res, [](CandidateList& c) { return not c.empty(); });
return it == end(res) ? CandidateList{} : std::move(*it);
} }
template<typename Container> template<typename Container>