summaryrefslogtreecommitdiffstats
path: root/lib/command_match.c
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-12-02 22:02:51 +0100
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-12-02 22:02:51 +0100
commit1e35decffd9b5f9563337dd9b1b17cc0dcd1ebe6 (patch)
tree3b1fdb7173c0e90ca25938645d9fe20718c649be /lib/command_match.c
parenttools: drop cmd_check.py (diff)
downloadfrr-1e35decffd9b5f9563337dd9b1b17cc0dcd1ebe6.tar.xz
frr-1e35decffd9b5f9563337dd9b1b17cc0dcd1ebe6.zip
lib: make CLI completions less surprising
* If a token matches exactly at the end of input, it still shows up in completions, e.g. ex# clear<?> clear Reset functions ex(config)# ip route 1.2.3.4<?> A.B.C.D IP destination prefix A.B.C.D/M IP destination prefix (e.g. 10.0.0.0/8) * If a token in mid-line exactly matches one token and partially matches on one or more additional tokens, the command tree(s) under the partially matching tokens will be ignored in favor of the exact match when compiling completions for the full line, e.g. ex(config)# ip <?> will only show completions for commands under 'ip' and not those under 'ipv6', which the input partially matches. Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'lib/command_match.c')
-rw-r--r--lib/command_match.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/lib/command_match.c b/lib/command_match.c
index 25309654f..f3f7d3998 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -125,7 +125,7 @@ command_match (struct graph *cmdgraph,
}
if (!*el) {
- trace_matcher ("No match");
+ trace_matcher ("No match\n");
}
else {
trace_matcher ("Matched command\n->string %s\n->desc %s\n", (*el)->string, (*el)->doc);
@@ -343,6 +343,13 @@ command_complete (struct graph *graph,
input_token = vector_slot (vline, idx);
+ int exact_match_exists = 0;
+ for (ALL_LIST_ELEMENTS_RO (current,node,gn))
+ if (!exact_match_exists)
+ exact_match_exists = (match_token (gn->data, input_token) == exact_match);
+ else
+ break;
+
for (ALL_LIST_ELEMENTS_RO (current,node,gn))
{
struct cmd_token *token = gn->data;
@@ -351,32 +358,28 @@ command_complete (struct graph *graph,
continue;
enum match_type minmatch = min_match_level (token->type);
- trace_matcher ("\"%s\" matches \"%s\" (%d) ? ", input_token, token->text, token->type);
+ trace_matcher ("\"%s\" matches \"%s\" (%d) ? ",
+ input_token, token->text, token->type);
+ unsigned int last_token = (vector_active (vline) - 1 == idx);
switch (match_token (token, input_token))
{
+ // occurs when last token is whitespace
case trivial_match:
trace_matcher ("trivial_match\n");
- assert(idx == vector_active (vline) - 1);
+ assert(last_token);
listnode_add (next, gn);
break;
case partly_match:
- trace_matcher ("partly_match\n");
- // last token on line is partial and
- // not a space
- if (idx == vector_active (vline) - 1)
- {
- listnode_add (next, gn);
- break;
- }
- if (minmatch <= partly_match)
- add_nexthops (next, gn);
-
- break;
+ trace_matcher ("trivial_match\n");
+ if (exact_match_exists && !last_token)
+ break;
case exact_match:
trace_matcher ("exact_match\n");
- add_nexthops (next, gn);
- listnode_add (next, gn);
+ if (last_token)
+ listnode_add (next, gn);
+ else
+ add_nexthops (next, gn);
break;
default:
trace_matcher ("no_match\n");