summaryrefslogtreecommitdiff
path: root/src/completion.hh
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-12-23 13:54:09 +0000
committerMaxime Coste <frrrwww@gmail.com>2014-12-23 13:54:09 +0000
commitb6ff15aa757eb35fed5772d28e3c06b5e844a49e (patch)
treed41ebca1b4fe4591017f5310749b263047ba9345 /src/completion.hh
parent064fb81b8d38df3bc77e2211fb6bc5db84fedb97 (diff)
Unify completion from container content logic
Diffstat (limited to 'src/completion.hh')
-rw-r--r--src/completion.hh38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/completion.hh b/src/completion.hh
index afaf6fbc..e978d0ac 100644
--- a/src/completion.hh
+++ b/src/completion.hh
@@ -53,5 +53,43 @@ inline Completions offset_pos(Completions completion, ByteCount offset)
std::move(completion.candidates) };
}
+namespace detail
+{
+ template<typename Str, typename Func>
+ void do_matches(Str&& str, StringView prefix,
+ CandidateList* res, Func match_func)
+ {
+ if (match_func(str, prefix))
+ res->push_back(str);
+ }
+
+ template<typename Str, typename Func, typename... Rest>
+ void do_matches(Str&& str, StringView prefix,
+ CandidateList* res, Func match_func, Rest... rest)
+ {
+ do_matches(str, prefix, res, match_func);
+ do_matches(str, prefix, res+1, rest...);
+ }
+}
+
+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);
+}
+
+template<typename Container>
+CandidateList complete(StringView prefix, ByteCount cursor_pos,
+ const Container& container)
+{
+ return complete(prefix, cursor_pos, container, prefix_match);
+}
+
}
#endif // completion_hh_INCLUDED