#ifndef completion_hh_INCLUDED #define completion_hh_INCLUDED #include #include #include "units.hh" #include "string.hh" #include "vector.hh" #include "ranked_match.hh" namespace Kakoune { class Context; using CandidateList = Vector; struct Completions { enum class Flags { None = 0, Quoted = 0b1, Menu = 0b10 }; constexpr friend bool with_bit_ops(Meta::Type) { return true; } CandidateList candidates; ByteCount start; ByteCount end; Flags flags = Flags::None; Completions() : start(0), end(0) {} Completions(ByteCount start, ByteCount end) : start(start), end(end) {} Completions(ByteCount start, ByteCount end, CandidateList candidates, Flags flags = Flags::None) : candidates(std::move(candidates)), start(start), end(end), flags{flags} {} }; enum class CompletionFlags { None = 0, Fast = 1 << 0, Start = 1 << 2, }; constexpr bool with_bit_ops(Meta::Type) { return true; } inline Completions complete_nothing(const Context&, CompletionFlags, StringView, ByteCount cursor_pos) { return {cursor_pos, cursor_pos}; } Completions shell_complete(const Context& context, CompletionFlags, StringView, ByteCount cursor_pos); inline Completions offset_pos(Completions completion, ByteCount offset) { return {completion.start + offset, completion.end + offset, std::move(completion.candidates), completion.flags}; } template CandidateList complete(StringView query, ByteCount cursor_pos, const Container& container) { using std::begin; static_assert(not std::is_same::value, "complete require long lived strings, not temporaries"); query = query.substr(0, cursor_pos); Vector matches; for (const auto& str : container) { if (RankedMatch match{str, query}) matches.push_back(match); } std::sort(matches.begin(), matches.end()); CandidateList res; for (auto& m : matches) res.push_back(m.candidate().str()); return res; } } #endif // completion_hh_INCLUDED