The way we currently call completer callbacks is that if we've
found --option that user wants to complete value for and it has
callback set then the callback is called.
And just before that, if no --option to have the value completed
is found or is found and is of boolean type then a list of
--option is generated (for given command).
But these two conditions can never be true at the same time
because boolean type of --options do not accept values. Therefore
the calling of completer callback can be promoted onto the same
level as the --option list generation.
This means that merging of two lists can be dropped to and
completer callback can store its retval directly into @list (but
as shown earlier one of the string lists to merge is always
empty).
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tools/vsh.c | 44 +++++++++++++++++++-------------------------
1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/tools/vsh.c b/tools/vsh.c
index e0dbda04c8..0d3c4fd7c7 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -2750,34 +2750,28 @@ vshReadlineParse(const char *text, int state)
if (!cmd) {
list = vshReadlineCommandGenerator(text);
- } else {
- if (!opt || opt->type == VSH_OT_BOOL)
- list = vshReadlineOptionsGenerator(text, cmd, partial);
+ } else if (!opt || opt->type == VSH_OT_BOOL) {
+ list = vshReadlineOptionsGenerator(text, cmd, partial);
+ } else if (opt && opt->completer) {
+ list = opt->completer(autoCompleteOpaque,
+ partial,
+ opt->completer_flags);
+ }
- if (opt && opt->completer) {
- g_auto(GStrv) completer_list = opt->completer(autoCompleteOpaque,
- partial,
- opt->completer_flags);
+ /* Escape completions, if needed (i.e. argument
+ * we are completing wasn't started with a quote
+ * character). This also enables filtering done
+ * below to work properly. */
+ if (list &&
+ !rl_completion_quote_character) {
+ size_t i;
- /* Escape completions, if needed (i.e. argument
- * we are completing wasn't started with a quote
- * character). This also enables filtering done
- * below to work properly. */
- if (completer_list &&
- !rl_completion_quote_character) {
- size_t i;
+ for (i = 0; list[i]; i++) {
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
- for (i = 0; completer_list[i]; i++) {
- g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
-
- virBufferEscape(&buf, '\\', " ",
"%s", completer_list[i]);
- VIR_FREE(completer_list[i]);
- completer_list[i] = virBufferContentAndReset(&buf);
- }
- }
-
- if (virStringListMerge(&list, &completer_list) < 0)
- goto cleanup;
+ virBufferEscape(&buf, '\\', " ", "%s",
list[i]);
+ VIR_FREE(list[i]);
+ list[i] = virBufferContentAndReset(&buf);
}
}
--
2.26.2