[libvirt] [PATCH 07/11] vsh: Introduce complete command

Martin Kletzander mkletzan at redhat.com
Wed Nov 8 15:33:58 UTC 2017


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 <mprivozn at 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20171108/add9cc16/attachment-0001.sig>


More information about the libvir-list mailing list