On Tue, Nov 07, 2017 at 01:22:55PM +0100, Michal Privoznik wrote:
This command is going to be called from bash completion script in
the following form:

 virsh complete "start --domain"

Its only purpose is to return list of possible strings for
completion. Note that this is a 'hidden', unlisted command and
therefore there's no documentation to it.

Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
---
tools/virsh.c      |  1 +
tools/virt-admin.c |  1 +
tools/vsh.c        | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/vsh.h        | 14 +++++++++++
4 files changed, 84 insertions(+)

diff --git a/tools/virsh.c b/tools/virsh.c
index 7d6dc2620..f830331f6 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -846,6 +846,7 @@ static const vshCmdDef virshCmds[] = {
    VSH_CMD_PWD,
    VSH_CMD_QUIT,
    VSH_CMD_SELF_TEST,
+    VSH_CMD_COMPLETE,
    {.name = "connect",
     .handler = cmdConnect,
     .opts = opts_connect,
diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index 5d7ef7988..c24ed95c0 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -1356,6 +1356,7 @@ static const vshCmdDef vshAdmCmds[] = {
    VSH_CMD_PWD,
    VSH_CMD_QUIT,
    VSH_CMD_SELF_TEST,
+    VSH_CMD_COMPLETE,
    {.name = "uri",
     .handler = cmdURI,
     .opts = NULL,
diff --git a/tools/vsh.c b/tools/vsh.c
index 121669574..136acb0ab 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -3419,3 +3419,71 @@ cmdSelfTest(vshControl *ctl ATTRIBUTE_UNUSED,

    return true;
}
+
+/* ----------------------
+ * Autocompletion command
+ * ---------------------- */
+
+const vshCmdOptDef opts_complete[] = {
+    {.name = "string",
+     .type = VSH_OT_ARGV,
+     .flags = VSH_OFLAG_EMPTY_OK,
+     .help = N_("partial string to autocomplete")
+    },
+    {.name = NULL}
+};
+
+const vshCmdInfo info_complete[] = {
+    {.name = "help",
+     .data = N_("internal command for autocompletion")
+    },
+    {.name = "desc",
+     .data = N_("internal use only")
+    },
+    {.name = NULL}
+};
+
+bool
+cmdComplete(vshControl *ctl, const vshCmd *cmd)
+{
+    bool ret = false;
+#ifdef WITH_READLINE
+    const vshClientHooks *hooks = ctl->hooks;
+    int stdin_fileno = STDIN_FILENO;
+    const char *arg = NULL;
+    char **matches = NULL, *tmp = NULL, **iter;
+
+    if (vshCommandOptStringQuiet(ctl, cmd, "string", &arg) <= 0)
+        goto cleanup;
+
+    /* This command is flagged VSH_CMD_FLAG_NOCONNECT because we
+     * need to prevent auth hooks reading any input. Therefore we
+     * have to close stdin and then connect ourselves. */
+    VIR_FORCE_CLOSE(stdin_fileno);
+
+    if (!(hooks && hooks->connHandler && hooks->connHandler(ctl, true)))
+        goto cleanup;
+
+    autoCompleteOpaque = ctl;
+
+    rl_basic_word_break_characters = " \t\n\\`@$><=;|&{(";
+    if (VIR_STRDUP(rl_line_buffer, arg) < 0)
+        goto cleanup;
+
+    while ((tmp = strpbrk(arg, rl_basic_word_break_characters)))
+        arg = tmp + 1;
+
+    if (!(matches = vshReadlineCompletion(arg, 0, 0)))
+        goto cleanup;
+

One more thing here, you're skipping to the last arg here, I guess this is the
reason why <TAB><TAB> doesn't work in the middle of the input, only at the end.
Maybe there should be another optional parameter that would tell you where the
completion was requested.

Attachment: signature.asc
Description: Digital signature

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to