Tab completion for list keys
Change-Id: Ifbebd0e27d3a26237c12e5492a2737612fc7a644
diff --git a/src/ast_handlers.cpp b/src/ast_handlers.cpp
new file mode 100644
index 0000000..ca5fe25
--- /dev/null
+++ b/src/ast_handlers.cpp
@@ -0,0 +1,15 @@
+#include "ast_handlers.hpp"
+std::set<std::string> generateMissingKeyCompletionSet(std::set<std::string> keysNeeded, std::set<std::string> currentSet)
+{
+ std::set<std::string> missingKeys;
+ std::set_difference(keysNeeded.begin(), keysNeeded.end(),
+ currentSet.begin(), currentSet.end(),
+ std::inserter(missingKeys, missingKeys.end()));
+
+ std::set<std::string> res;
+
+ std::transform(missingKeys.begin(), missingKeys.end(),
+ std::inserter(res, res.end()),
+ [] (auto it) { return it + "="; });
+ return res;
+}
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index b9b9101..5a55f36 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -11,6 +11,9 @@
#include "parser_context.hpp"
#include "schema.hpp"
#include "utils.hpp"
+namespace x3 = boost::spirit::x3;
+
+struct parser_context_tag;
struct keyValue_class {
template <typename T, typename Iterator, typename Context>
@@ -498,3 +501,36 @@
parserContext.m_suggestions = schema.childNodes(parserContext.m_curPath, Recursion::NonRecursive);
}
};
+
+std::set<std::string> generateMissingKeyCompletionSet(std::set<std::string> keysNeeded, std::set<std::string> currentSet);
+
+struct createKeySuggestions_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);
+ const auto& schema = parserContext.m_schema;
+
+ parserContext.m_completionIterator = begin;
+
+ const auto& keysNeeded = schema.listKeys(parserContext.m_curPath, {parserContext.m_curModule, parserContext.m_tmpListName});
+ parserContext.m_suggestions = generateMissingKeyCompletionSet(keysNeeded, parserContext.m_tmpListKeys);
+ }
+};
+
+struct suggestKeysEnd_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);
+ const auto& schema = parserContext.m_schema;
+
+ parserContext.m_completionIterator = begin;
+ const auto& keysNeeded = schema.listKeys(parserContext.m_curPath, {parserContext.m_curModule, parserContext.m_tmpListName});
+ if (generateMissingKeyCompletionSet(keysNeeded, parserContext.m_tmpListKeys).empty()) {
+ parserContext.m_suggestions = {"]/"};
+ } else {
+ parserContext.m_suggestions = {"]"};
+ }
+ }
+};
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 79cd17a..2bf7be4 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -55,6 +55,8 @@
x3::rule<initializePath_class, x3::unused_type> const initializePath = "initializePath";
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";
#if __clang__
#pragma GCC diagnostic push
@@ -73,8 +75,17 @@
auto const number =
+x3::digit;
+auto const createKeySuggestions_def =
+ x3::eps;
+
+auto const suggestKeysEnd_def =
+ x3::eps;
+
auto const keyValue_def =
- lexeme['[' > key_identifier > '=' > (quotedValue | number) > ']'];
+ key_identifier > '=' > (quotedValue | number);
+
+auto const keyValueWrapper =
+ lexeme['[' > createKeySuggestions > keyValue > suggestKeysEnd > ']'];
auto const module_identifier_def =
lexeme[
@@ -91,7 +102,7 @@
// even though we don't allow no keys to be supplied, the star allows me to check which keys are missing
auto const listSuffix_def =
- *keyValue;
+ *keyValueWrapper;
auto const listElement_def =
listPrefix > listSuffix;
@@ -272,3 +283,5 @@
BOOST_SPIRIT_DEFINE(delete_rule)
BOOST_SPIRIT_DEFINE(command)
BOOST_SPIRIT_DEFINE(createPathSuggestions)
+BOOST_SPIRIT_DEFINE(createKeySuggestions)
+BOOST_SPIRIT_DEFINE(suggestKeysEnd)