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

Reply via email to