The idea is that .completer for vshCmdOptDef would be called if
the last token on the input is a cmd opt. For instance:
virsh # start --domain<TAB><TAB>
However, with current code that's not happening.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tools/vsh.c | 48 ++++++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/tools/vsh.c b/tools/vsh.c
index bad2c0bcf..3ed6bb916 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -2691,7 +2691,7 @@ vshReadlineParse(const char *text, int state)
uint64_t opts_seen;
size_t opt_index;
static bool cmd_exists, opts_filled, opt_exists;
- static bool non_bool_opt_exists, data_complete;
+ static bool non_bool_opt_exists, complete_data, complete_opts;
if (!state) {
parser.pos = rl_line_buffer;
@@ -2738,7 +2738,7 @@ vshReadlineParse(const char *text, int state)
cmd_exists = false;
opts_filled = false;
non_bool_opt_exists = false;
- data_complete = false;
+ complete_data = false;
const_opts_need_arg = 0;
const_opts_required = 0;
@@ -2804,7 +2804,7 @@ vshReadlineParse(const char *text, int state)
}
if (STREQ(tkdata, sanitized_text)) {
/* auto-complete non-bool option arg */
- data_complete = true;
+ complete_data = true;
break;
}
non_bool_opt_exists = false;
@@ -2851,27 +2851,36 @@ vshReadlineParse(const char *text, int state)
virSkipSpaces((const char**)&tkdata);
}
VIR_FREE(const_tkdata);
+ complete_opts = opts_filled && !non_bool_opt_exists;
}
if (!cmd_exists) {
res = vshReadlineCommandGenerator(sanitized_text, state);
- } else if (opts_filled && !non_bool_opt_exists) {
- res = vshReadlineOptionsGenerator(sanitized_text, state, cmd);
- } else if (non_bool_opt_exists && data_complete && opt &&
opt->completer) {
- if (!completed_list)
- completed_list = opt->completer(autoCompleteOpaque,
- opt->completer_flags);
- if (completed_list) {
- while ((completed_name = completed_list[completed_list_index])) {
- completed_list_index++;
- if (!STRPREFIX(completed_name, sanitized_text))
- continue;
- res = vshStrdup(NULL, completed_name);
- return res;
+ } else {
+ if (complete_opts) {
+ res = vshReadlineOptionsGenerator(sanitized_text, state, cmd);
+ complete_opts = !!res;
+ }
+
+ if (!complete_opts && complete_data) {
+ if (!completed_list && opt && opt->completer)
+ completed_list = opt->completer(autoCompleteOpaque,
+ opt->completer_flags);
+ if (completed_list) {
+ while ((completed_name = completed_list[completed_list_index])) {
+ completed_list_index++;
+ if (!STRPREFIX(completed_name, sanitized_text))
+ continue;
+ res = vshStrdup(NULL, completed_name);
+ break;
+ }
+
+ if (!res) {
+ virStringListFree(completed_list);
+ completed_list = NULL;
+ completed_list_index = 0;
+ }
}
- res = NULL;
- virStringListFree(completed_list);
- completed_list_index = 0;
}
}
@@ -2895,7 +2904,6 @@ vshReadlineParse(const char *text, int state)
VIR_FREE(sanitized_text);
VIR_FREE(ctext);
return NULL;
-
}
static char **
--
2.13.6