This patch introduces a way for completers to retrieve the current vshControl object by using the vshGetCompleterCtl() macro. When readline is enabled, the main method stores the vshControl pointer in a variable that is file-global to virsh.c. Then, that pointer can be retrieved by the _vshGetCompleterCtl() function, which is mapped to by the macro. If readline is not enabled, the macro simply maps to NULL. --- tools/virsh.c | 28 +++++++++++++++++++++++++--- tools/virsh.h | 8 ++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 2ac0875..972cc5d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -95,6 +95,15 @@ static char *progname; static const vshCmdGrp cmdGroups[]; +#if WITH_READLINE +static vshControl *completer_ctl; + +vshControl * +_vshGetCompleterCtl(void) { + return completer_ctl; +} +#endif + /* Bypass header poison */ #undef strdup @@ -3005,7 +3014,7 @@ vshReadlineCommandGenerator(const char *text, int state) } static char * -vshDelegateToCustomCompleter(const vshCmdOptDef *opt, +vshDelegateToCustomCompleter(const vshCmdOptDef *opt, bool reconnect, const char *text, int state) { static int list_index; @@ -3018,6 +3027,10 @@ vshDelegateToCustomCompleter(const vshCmdOptDef *opt, return NULL; if (opt->completer) { + vshControl *ctl = completer_ctl; + if ((!ctl->conn || disconnected) && reconnect) + vshReconnect(ctl); + list_index = 0; completions = opt->completer(opt->completer_flags); } @@ -3131,7 +3144,9 @@ vshReadlineOptionsGenerator(const char *text, int state) return NULL; if (waiting_for_flag_arg) { - char* res = vshDelegateToCustomCompleter(curr_opt, text, substate); + bool may_connect = !(cmd->flags & VSH_CMD_FLAG_NOCONNECT); + char* res = vshDelegateToCustomCompleter(curr_opt, may_connect, + text, substate); substate++; /* if we're in a flag's argument, we don't * want to show other flags */ @@ -3159,7 +3174,9 @@ vshReadlineOptionsGenerator(const char *text, int state) /* we don't need to ignore args without custom completers, * since vshDelegateToCustomCompleter will do this for us */ - res = vshDelegateToCustomCompleter(opt, text, substate); + bool may_connect = !(cmd->flags & VSH_CMD_FLAG_NOCONNECT); + res = vshDelegateToCustomCompleter(opt, may_connect, + text, substate); substate++; if (res) { return res; @@ -3801,9 +3818,14 @@ int main(int argc, char **argv) { vshControl _ctl, *ctl = &_ctl; + const char *defaultConn; bool ret = true; +#if WITH_READLINE + completer_ctl = ctl; +#endif + memset(ctl, 0, sizeof(vshControl)); ctl->imode = true; /* default is interactive mode */ ctl->log_fd = -1; /* Initialize log file descriptor */ diff --git a/tools/virsh.h b/tools/virsh.h index 113d1e5..a8977ab 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -180,6 +180,14 @@ struct _vshCmdOptDef { * readline file completer */ # define VSH_COMPLETE_AS_FILE (1 << 8) +vshControl * _vshGetCompleterCtl(void); + +#if WITH_READLINE +# define vshGetCompleterCtl() _vshGetCompleterCtl() +#else +# define vshGetCompleterCtl() NULL +#endif + /* * vshCmdOpt - command options * -- 1.8.3.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list