From: Chen Hanxiao <chenhanxiao@xxxxxxxxxxxxxx> If we need to exclude one parameters from another, we could use this member to specify one. With this flag, we could archive what Eric comment on: https://www.redhat.com/archives/libvir-list/2013-October/msg00965.html 1. COMMAND <TAB> or COMMAND --<TAB> Auto complete will NOT show option that marked as VSH_OT_ALIAS 2. COMMAND --sh<TAB> Auto complete will show --shareable (this one was marked as VSH_OT_ALIAS) 3. COMMAND --mode XXX <TAB> or COMMAND --mode XXX --sh<TAB> Auto complete will NOT show --shareable (we set new member exclude_option for mode) 4. COMMAND --shareable --mo<TAB> Auto complete will NOT show --mode (we set new member exclude_option for mode) Signed-off-by: Chen Hanxiao <chenhanxiao@xxxxxxxxxxxxxx> --- v2: use camelCase for struct members enable excludeOption to hold more than one options by a comma seperated string. tools/virsh.c | 34 ++++++++++++++++++++++++++++++++++ tools/virsh.h | 1 + 2 files changed, 35 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index bad78c9..f26e567 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2686,11 +2686,16 @@ vshReadlineOptionsGenerator(const char *text, int state) static int list_index, len; static const vshCmdDef *cmd = NULL; const char *name; + size_t size_opt = 0; + static char *excludeStr = NULL; + char *tmp_str = NULL; + const char *excludeOption; if (!state) { /* determine command name */ char *p; char *cmdname; + size_t length = 0; if (!(p = strchr(rl_line_buffer, ' '))) return NULL; @@ -2698,7 +2703,29 @@ vshReadlineOptionsGenerator(const char *text, int state) cmdname = vshCalloc(NULL, (p - rl_line_buffer) + 1, 1); memcpy(cmdname, rl_line_buffer, p - rl_line_buffer); + /* collect exclude options */ + VIR_FREE(excludeStr); cmd = vshCmddefSearch(cmdname); + while ((name = cmd->opts[size_opt].name)) { + if ((strstr(rl_line_buffer, name)) && + (excludeOption = cmd->opts[size_opt].excludeOption)) { + if (excludeStr) + length = strlen(excludeStr) + 2; + + tmp_str = vshCalloc(NULL, length + strlen(excludeOption) + 2, 1); + + if (excludeStr) { + memcpy(tmp_str, excludeStr, length - 2); + strcat(tmp_str, ","); + } + strcat(tmp_str, excludeOption); + excludeStr = vshStrdup(NULL, tmp_str); + VIR_FREE(tmp_str); + length = 0; + } + size_opt++; + } + list_index = 0; len = strlen(text); VIR_FREE(cmdname); @@ -2720,6 +2747,13 @@ vshReadlineOptionsGenerator(const char *text, int state) /* ignore non --option */ continue; + if (len == 2 && opt->type == VSH_OT_ALIAS) + continue; + + /* ignore confict options */ + if ((excludeStr) &&(strstr(excludeStr, name))) + continue; + if (len > 2) { if (STRNEQLEN(name, text + 2, len - 2)) continue; diff --git a/tools/virsh.h b/tools/virsh.h index b843788..c916911 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -173,6 +173,7 @@ struct _vshCmdOptDef { * the name of a later public option */ vshCompleter completer; /* option completer */ unsigned int completer_flags; /* option completer flags */ + const char *excludeOption; /* check the exclusion of option, string seperate by ',' */ }; /* -- 1.8.2.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list