[libvirt] [PATCH 3/5] Improve virsh autocompletion (global ctl object)

Solly Ross sross at redhat.com
Sun Mar 30 02:36:11 UTC 2014


This patch introduces a way for completers to retrieve the
current vshControl object by using the vshGetCompleterCtl()
macro.  When readline is enabled, the main method stores the
vshControl pointer in a variable that is file-global to virsh.c.
Then, that pointer can be retrieved by the _vshGetCompleterCtl()
function, which is mapped to by the macro.  If readline is not
enabled, the macro simply maps to NULL.
---
 tools/virsh.c | 28 +++++++++++++++++++++++++---
 tools/virsh.h |  8 ++++++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 2ac0875..972cc5d 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -95,6 +95,15 @@ static char *progname;
 
 static const vshCmdGrp cmdGroups[];
 
+#if WITH_READLINE
+static vshControl *completer_ctl;
+
+vshControl *
+_vshGetCompleterCtl(void) {
+    return completer_ctl;
+}
+#endif
+
 /* Bypass header poison */
 #undef strdup
 
@@ -3005,7 +3014,7 @@ vshReadlineCommandGenerator(const char *text, int state)
 }
 
 static char *
-vshDelegateToCustomCompleter(const vshCmdOptDef *opt,
+vshDelegateToCustomCompleter(const vshCmdOptDef *opt, bool reconnect,
                              const char *text, int state)
 {
     static int list_index;
@@ -3018,6 +3027,10 @@ vshDelegateToCustomCompleter(const vshCmdOptDef *opt,
             return NULL;
 
         if (opt->completer) {
+            vshControl *ctl = completer_ctl;
+            if ((!ctl->conn || disconnected) && reconnect)
+                vshReconnect(ctl);
+
             list_index = 0;
             completions = opt->completer(opt->completer_flags);
         }
@@ -3131,7 +3144,9 @@ vshReadlineOptionsGenerator(const char *text, int state)
         return NULL;
 
     if (waiting_for_flag_arg) {
-        char* res = vshDelegateToCustomCompleter(curr_opt, text, substate);
+        bool may_connect = !(cmd->flags & VSH_CMD_FLAG_NOCONNECT);
+        char* res = vshDelegateToCustomCompleter(curr_opt, may_connect,
+                                                 text, substate);
         substate++;
         /* if we're in a flag's argument, we don't
          * want to show other flags */
@@ -3159,7 +3174,9 @@ vshReadlineOptionsGenerator(const char *text, int state)
 
             /* we don't need to ignore args without custom completers,
              * since vshDelegateToCustomCompleter will do this for us */
-            res = vshDelegateToCustomCompleter(opt, text, substate);
+            bool may_connect = !(cmd->flags & VSH_CMD_FLAG_NOCONNECT);
+            res = vshDelegateToCustomCompleter(opt, may_connect,
+                                               text, substate);
             substate++;
             if (res) {
                 return res;
@@ -3801,9 +3818,14 @@ int
 main(int argc, char **argv)
 {
     vshControl _ctl, *ctl = &_ctl;
+
     const char *defaultConn;
     bool ret = true;
 
+#if WITH_READLINE
+    completer_ctl = ctl;
+#endif
+
     memset(ctl, 0, sizeof(vshControl));
     ctl->imode = true;          /* default is interactive mode */
     ctl->log_fd = -1;           /* Initialize log file descriptor */
diff --git a/tools/virsh.h b/tools/virsh.h
index 113d1e5..a8977ab 100644
--- a/tools/virsh.h
+++ b/tools/virsh.h
@@ -180,6 +180,14 @@ struct _vshCmdOptDef {
  * readline file completer */
 # define VSH_COMPLETE_AS_FILE (1 << 8)
 
+vshControl * _vshGetCompleterCtl(void);
+
+#if WITH_READLINE
+# define vshGetCompleterCtl() _vshGetCompleterCtl()
+#else
+# define vshGetCompleterCtl() NULL
+#endif
+
 /*
  * vshCmdOpt - command options
  *
-- 
1.8.3.2




More information about the libvir-list mailing list