Tab completion for commands
Change-Id: Ia38120da7b45cb75effcb2c93eee148419c2fa09
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index 787fb94..3a59e26 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -7,6 +7,7 @@
*/
#pragma once
+#include <boost/mpl/vector.hpp>
#include "ast_path.hpp"
#include "ast_values.hpp"
@@ -34,46 +35,57 @@
};
struct discard_ : x3::position_tagged {
+ static constexpr auto name = "discard";
bool operator==(const discard_& b) const;
};
struct ls_ : x3::position_tagged {
+ static constexpr auto name = "ls";
bool operator==(const ls_& b) const;
std::vector<LsOption> m_options;
boost::optional<boost::variant<dataPath_, schemaPath_>> m_path;
};
struct cd_ : x3::position_tagged {
+ static constexpr auto name = "cd";
bool operator==(const cd_& b) const;
dataPath_ m_path;
};
struct create_ : x3::position_tagged {
+ static constexpr auto name = "create";
bool operator==(const create_& b) const;
dataPath_ m_path;
};
struct delete_ : x3::position_tagged {
+ static constexpr auto name = "delete";
bool operator==(const delete_& b) const;
dataPath_ m_path;
};
struct set_ : x3::position_tagged {
+ static constexpr auto name = "set";
bool operator==(const set_& b) const;
dataPath_ m_path;
leaf_data_ m_data;
};
struct commit_ : x3::position_tagged {
+ static constexpr auto name = "commit";
bool operator==(const set_& b) const;
};
struct get_ : x3::position_tagged {
+ static constexpr auto name = "get";
bool operator==(const get_& b) const;
boost::optional<boost::variant<dataPath_, schemaPath_>> m_path;
};
-using command_ = boost::variant<discard_, ls_, cd_, create_, delete_, set_, commit_, get_>;
+// TODO: The usage of MPL won't be necessary after std::variant support is added to Spirit
+// https://github.com/boostorg/spirit/issues/270
+using CommandTypes = boost::mpl::vector<discard_, ls_, cd_, create_, delete_, set_, commit_, get_>;
+using command_ = boost::make_variant_over<CommandTypes>::type;
BOOST_FUSION_ADAPT_STRUCT(ls_, m_options, m_path)
BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 5a55f36..f0bbf4c 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -8,6 +8,8 @@
#pragma once
+#include <boost/mpl/for_each.hpp>
+#include "ast_commands.hpp"
#include "parser_context.hpp"
#include "schema.hpp"
#include "utils.hpp"
@@ -534,3 +536,25 @@
}
}
};
+
+struct commandNamesVisitor {
+ template <typename T>
+ auto operator()(boost::type<T>)
+ {
+ return T::name;
+ }
+};
+
+struct createCommandSuggestions_class {
+ template <typename T, typename Iterator, typename Context>
+ void on_success(Iterator const& begin, Iterator const&, T&, Context const& context)
+ {
+ auto& parserContext = x3::get<parser_context_tag>(context);
+ parserContext.m_completionIterator = begin;
+
+ parserContext.m_suggestions.clear();
+ boost::mpl::for_each<CommandTypes, boost::type<boost::mpl::_>>([&parserContext](auto cmd) {
+ parserContext.m_suggestions.emplace(commandNamesVisitor()(cmd));
+ });
+ }
+};
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 2bf7be4..e532174 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -57,6 +57,7 @@
x3::rule<createPathSuggestions_class, x3::unused_type> const createPathSuggestions = "createPathSuggestions";
x3::rule<createKeySuggestions_class, x3::unused_type> const createKeySuggestions = "createKeySuggestions";
x3::rule<suggestKeysEnd_class, x3::unused_type> const suggestKeysEnd = "suggestKeysEnd";
+x3::rule<createCommandSuggestions_class, x3::unused_type> const createCommandSuggestions = "createCommandSuggestions";
#if __clang__
#pragma GCC diagnostic push
@@ -236,8 +237,11 @@
auto const discard_def =
lit("discard") >> x3::attr(discard_());
+auto const createCommandSuggestions_def =
+ x3::eps;
+
auto const command_def =
- x3::expect[cd | create | delete_rule | set | commit | get | ls | discard];
+ createCommandSuggestions >> x3::expect[cd | create | delete_rule | set | commit | get | ls | discard];
#if __clang__
#pragma GCC diagnostic pop
@@ -285,3 +289,4 @@
BOOST_SPIRIT_DEFINE(createPathSuggestions)
BOOST_SPIRIT_DEFINE(createKeySuggestions)
BOOST_SPIRIT_DEFINE(suggestKeysEnd)
+BOOST_SPIRIT_DEFINE(createCommandSuggestions)