On Wed, Nov 08, 2017 at 04:00:35PM +0100, Michal Privoznik wrote:
On 11/08/2017 03:23 PM, Martin Kletzander wrote: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; + + for (iter = matches; *iter; iter++) + printf("%s\n", *iter); + + ret = true; + cleanup: + for (iter = matches; iter && *iter; iter++) + VIR_FREE(*iter); + VIR_FREE(matches); +#endif /* WITH_READLINE */Do we really need readline for it? Did I miss something or are we really just using it here just so we don't have to split the vshReadlineParse() in some way? Don't get me wrong, I'm OK with that, the split would be too complicated and who doesn't use readline, right? It just feels weird.Yes we do need readline unfortunately. vshReadlineCompletion() calls rl_completion_matches() which filters strings returned by vshReadlineParse() so that list of strings presented to user corresponds to their input. We could reimplement the rl_* function ourselves if we really want to be readline independent. On the other hand - readline is everywhere, so why should we bother?
Sure, I agree, my question was if this is using it just for filtering strings, looks like yes :D
Michal -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list