Suggest characters at ends of path fragments
The program now suggests a slash for containers, a space for leafs and a
left bracket for lists. The logic for suggesting the first the starting
bracket for lists got a little bit simplified, since it's now a part of
the list's identifier. The CLI now directly shows, if a
slash/bracket/space is going to be appended. The user can use this
information to deduce if a node is container/list/leaf.
Change-Id: Ib1a3cdd326a1451ba80f3bb48a9e8bdd13c102ae
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 5501247..75d8553 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -333,6 +333,7 @@
{
auto& parserContext = x3::get<parser_context_tag>(context);
parserContext.m_suggestions.clear();
+ parserContext.m_completionSuffix.clear();
}
};
@@ -556,7 +557,32 @@
const auto& schema = parserContext.m_schema;
parserContext.m_completionIterator = begin;
- parserContext.m_suggestions = schema.childNodes(parserContext.m_curPath, Recursion::NonRecursive);
+ auto suggestions = schema.childNodes(parserContext.m_curPath, Recursion::NonRecursive);
+ std::set<std::string> suffixesAdded;
+ std::transform(suggestions.begin(), suggestions.end(),
+ std::inserter(suffixesAdded, suffixesAdded.end()),
+ [&parserContext, &schema] (auto it) {
+ ModuleNodePair node;
+ if (auto colonPos = it.find(":"); colonPos != it.npos) {
+ node.first = it.substr(0, colonPos);
+ node.second = it.substr(colonPos + 1, node.second.npos);
+ } else {
+ node.first = boost::none;
+ node.second = it;
+ }
+
+ if (schema.isLeaf(parserContext.m_curPath, node)) {
+ return it + " ";
+ }
+ if (schema.isContainer(parserContext.m_curPath, node)) {
+ return it + "/";
+ }
+ if (schema.isList(parserContext.m_curPath, node)) {
+ return it + "[";
+ }
+ return it;
+ });
+ parserContext.m_suggestions = suffixesAdded;
}
};
@@ -593,16 +619,6 @@
}
};
-struct suggestKeysStart_class {
- template <typename T, typename Iterator, typename Context>
- void on_success(Iterator const&, Iterator const&, T&, Context const& context)
- {
- auto& parserContext = x3::get<parser_context_tag>(context);
-
- parserContext.m_completionSuffix = "[";
- }
-};
-
struct commandNamesVisitor {
template <typename T>
auto operator()(boost::type<T>)
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 4fd7b15..0a259b8 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -71,7 +71,6 @@
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<suggestKeysStart_class, x3::unused_type> const suggestKeysStart = "suggestKeysStart";
x3::rule<suggestKeysEnd_class, x3::unused_type> const suggestKeysEnd = "suggestKeysEnd";
x3::rule<createCommandSuggestions_class, x3::unused_type> const createCommandSuggestions = "createCommandSuggestions";
x3::rule<completing_class, x3::unused_type> const completing = "completing";
@@ -118,9 +117,6 @@
auto const createKeySuggestions_def =
x3::eps;
-auto const suggestKeysStart_def =
- x3::eps;
-
auto const suggestKeysEnd_def =
x3::eps;
@@ -148,7 +144,7 @@
*keyValueWrapper;
auto const listElement_def =
- listPrefix >> -(!char_('[') >> suggestKeysStart) >> &char_('[') > listSuffix;
+ listPrefix >> &char_('[') > listSuffix;
auto const list_def =
node_identifier >> !char_('[');
@@ -405,7 +401,6 @@
BOOST_SPIRIT_DEFINE(command)
BOOST_SPIRIT_DEFINE(createPathSuggestions)
BOOST_SPIRIT_DEFINE(createKeySuggestions)
-BOOST_SPIRIT_DEFINE(suggestKeysStart)
BOOST_SPIRIT_DEFINE(suggestKeysEnd)
BOOST_SPIRIT_DEFINE(createCommandSuggestions)
BOOST_SPIRIT_DEFINE(completing)
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index a3f59aa..60cddf9 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -107,6 +107,8 @@
void StaticSchema::addLeaf(const std::string& location, const std::string& name, const yang::LeafDataTypes& type)
{
m_nodes.at(location).emplace(name, yang::leaf{type, {}, {}, {}});
+ std::string key = joinPaths(location, name);
+ m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
}
void StaticSchema::addLeafEnum(const std::string& location, const std::string& name, std::set<std::string> enumValues)
@@ -115,6 +117,8 @@
toAdd.m_type = yang::LeafDataTypes::Enum;
toAdd.m_enumValues = enumValues;
m_nodes.at(location).emplace(name, toAdd);
+ std::string key = joinPaths(location, name);
+ m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
}
void StaticSchema::addLeafIdentityRef(const std::string& location, const std::string& name, const ModuleValuePair& base)
@@ -124,6 +128,8 @@
toAdd.m_type = yang::LeafDataTypes::IdentityRef;
toAdd.m_identBase = base;
m_nodes.at(location).emplace(name, toAdd);
+ std::string key = joinPaths(location, name);
+ m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
}
void StaticSchema::addLeafRef(const std::string& location, const std::string& name, const std::string& source)
@@ -132,6 +138,8 @@
toAdd.m_type = yang::LeafDataTypes::LeafRef;
toAdd.m_leafRefSource = source;
m_nodes.at(location).emplace(name, toAdd);
+ std::string key = joinPaths(location, name);
+ m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
}
void StaticSchema::addModule(const std::string& name)
diff --git a/tests/path_completion.cpp b/tests/path_completion.cpp
index 5adb7ff..c68cca0 100644
--- a/tests/path_completion.cpp
+++ b/tests/path_completion.cpp
@@ -51,25 +51,25 @@
SECTION("ls ")
{
input = "ls ";
- expected = {"example:ano", "example:anoda", "example:bota", "example:leafInt", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList", "second:amelie"};
+ expected = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list[", "example:ovoce[", "example:ovocezelenina[", "example:twoKeyList[", "second:amelie/"};
}
SECTION("ls e")
{
input = "ls e";
- expected = {"example:ano", "example:anoda", "example:bota", "example:leafInt", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList"};
+ expected = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list[", "example:ovoce[", "example:ovocezelenina[", "example:twoKeyList["};
}
SECTION("ls example:ano")
{
input = "ls example:ano";
- expected = {"example:ano", "example:anoda"};
+ expected = {"example:ano/", "example:anoda/"};
}
SECTION("ls example:ano/example:a")
{
input = "ls example:ano/example:a";
- expected = {"example:a2"};
+ expected = {"example:a2/"};
}
SECTION("ls x")
@@ -81,32 +81,44 @@
SECTION("ls /")
{
input = "ls /";
- expected = {"example:ano", "example:anoda", "example:bota", "example:leafInt", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList", "second:amelie"};
+ expected = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list[", "example:ovoce[", "example:ovocezelenina[", "example:twoKeyList[", "second:amelie/"};
}
SECTION("ls /e")
{
input = "ls /e";
- expected = {"example:ano", "example:anoda", "example:bota", "example:leafInt", "example:list", "example:ovoce", "example:ovocezelenina", "example:twoKeyList"};
+ expected = {"example:ano/", "example:anoda/", "example:bota/", "example:leafInt ", "example:list[", "example:ovoce[", "example:ovocezelenina[", "example:twoKeyList["};
}
+ SECTION("ls example:bota")
+ {
+ input = "ls example:bota";
+ expected = {"example:bota/"};
+ }
+
+ SECTION("ls /example:bota")
+ {
+ input = "ls /example:bota";
+ expected = {"example:bota/"};
+ }
+
SECTION("ls /s")
{
input = "ls /s";
- expected = {"second:amelie"};
+ expected = {"second:amelie/"};
}
SECTION("ls /example:list[number=3]/")
{
input = "ls /example:list[number=3]/";
- expected = {"example:contInList"};
+ expected = {"example:contInList/"};
}
SECTION("ls /example:list[number=3]/c")
{
input = "ls /example:list[number=3]/e";
- expected = {"example:contInList"};
+ expected = {"example:contInList/"};
}
SECTION("ls /example:list[number=3]/a")
@@ -121,7 +133,7 @@
SECTION("cd example:lis")
{
input = "cd example:lis";
- expected = {"example:list"};
+ expected = {"example:list["};
}
SECTION("set example:list")
@@ -211,7 +223,7 @@
SECTION("cd example:ovoce")
{
input = "cd example:ovoce";
- expected = {"example:ovoce", "example:ovocezelenina"};
+ expected = {"example:ovoce[", "example:ovocezelenina["};
}
}