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 <mpriv...@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 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list