Custom readline generator will help for some usecase.
Also add a custom readline generator for the "help" command.
Signed-off-by: Lai Jiangshan <laijs(a)cn.fujitsu.com>
---
diff --git a/tools/virsh.c b/tools/virsh.c
index fcd254d..51e43c1 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13575,7 +13575,7 @@ vshCloseLogFile(vshControl *ctl)
* (i.e. STATE == 0), then we start at the top of the list.
*/
static char *
-vshReadlineCommandGenerator(const char *text, int state)
+vshReadlineCmdAndGrpGenerator(const char *text, int state, int grpname)
{
static int grp_list_index, cmd_list_index, len;
const char *name;
@@ -13604,8 +13604,13 @@ vshReadlineCommandGenerator(const char *text, int state)
return vshStrdup(NULL, name);
}
} else {
+ name = grp[grp_list_index].keyword;
cmd_list_index = 0;
grp_list_index++;
+
+ if (grpname && STREQLEN(name, text, len))
+ return vshStrdup(NULL, name);
+
}
}
@@ -13614,10 +13619,45 @@ vshReadlineCommandGenerator(const char *text, int state)
}
static char *
+vshReadlineCommandGenerator(const char *text, int state)
+{
+ return vshReadlineCmdAndGrpGenerator(text, state, 0);
+}
+
+static char *
+vshReadlineHelpOptionGenerator(const char *text, int state)
+{
+ return vshReadlineCmdAndGrpGenerator(text, state, 1);
+}
+
+struct vshCustomReadLine {
+ const char *name;
+ char *(*CustomReadLineOptionGenerator)(const char *text, int state);
+};
+
+struct vshCustomReadLine customeReadLine[] = {
+ { "help", vshReadlineHelpOptionGenerator },
+ { NULL, NULL }
+};
+
+static struct vshCustomReadLine *vshCustomReadLineSearch(const char *name)
+{
+ struct vshCustomReadLine *ret = customeReadLine;
+
+ for (ret = customeReadLine; ret->name; ret++) {
+ if (STREQ(ret->name, name))
+ return ret;
+ }
+
+ return NULL;
+}
+
+static char *
vshReadlineOptionsGenerator(const char *text, int state)
{
static int list_index, len;
static const vshCmdDef *cmd = NULL;
+ static const struct vshCustomReadLine *rl = NULL;
const char *name;
if (!state) {
@@ -13632,6 +13672,7 @@ vshReadlineOptionsGenerator(const char *text, int state)
memcpy(cmdname, rl_line_buffer, p - rl_line_buffer);
cmd = vshCmddefSearch(cmdname);
+ rl = vshCustomReadLineSearch(cmdname);
list_index = 0;
len = strlen(text);
VIR_FREE(cmdname);
@@ -13640,6 +13681,9 @@ vshReadlineOptionsGenerator(const char *text, int state)
if (!cmd)
return NULL;
+ if (rl)
+ return rl->CustomReadLineOptionGenerator(text, state);
+
if (!cmd->opts)
return NULL;