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