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
{
template<typename Str, typename Func>
void do_matches(Str&& str, StringView prefix,
CandidateList* res, Func match_func)
template<typename Container, typename Func>
void do_matches(Container&& container, StringView prefix,
CandidateList& res, Func match_func)
{
if (match_func(str, prefix))
res->push_back(str);
for (auto&& elem : container)
if (match_func(elem, prefix))
res.push_back(elem);
}
template<typename Str, typename Func, typename... Rest>
void do_matches(Str&& str, StringView prefix,
CandidateList* res, Func match_func, Rest... rest)
template<typename Container, typename Func, typename... Rest>
void do_matches(Container&& container, StringView prefix,
CandidateList& res, Func match_func, Rest... rest)
{
do_matches(str, prefix, res, match_func);
do_matches(str, prefix, res+1, rest...);
do_matches(container, prefix, res, match_func);
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,
const Container& container, MatchFunc... match_func)
{
CandidateList res[sizeof...(match_func)];
auto real_prefix = prefix.substr(0, cursor_pos);
for (const auto& elem : container)
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);
CandidateList res;
detail::do_matches(container, prefix.substr(0, cursor_pos), res, match_func...);
return res;
}
template<typename Container>