Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Zsh OpenStack completions

Marko Myllynen wrote on Tue, Sep 06, 2016 at 15:39:02 +0300:
> Hi,
> Below is a patch to add completions for several OpenStack related
> command line clients, including the new common client, openstack(1).
> There are three categories of clients:
> 1) newer clients which provide per-command sub-commands and options
> 2) old skool clients which provide the "bash-completion" command
> 3) an oddball, swift, slightly different than 2)

It would be useful to have this information in a comment above the
declaration of the corresponding arrays.

More generally: having block-level comments would be useful.  See for
example the computil.c part of 39173.  Without them the code would be
harder to work on in the future.

> We cache things pretty aggressively as something like "neutron help"
> takes ~0.75s on my laptop (compared to 0.002 of "ls --help") and
> openstack(1) even goes over the network for the list of completions.

A brilliant example of the pendulum tendency to take us all back to the
dumb terminals era of the 70's :-)

> (Also, searching for (sub)commands from the associative
> array doesn't look very nice but I'm not sure how to do that better
> while still making sure that e.g. net-list and net-list-on-dhcp-agent
> are not being confused - perhaps I missed a flag to aid in this.)

I assume you refer to this line? —

  for word in ${words:1}; do
    [[ $_cache_openstack_clnt_cmds[$service] != ${${${_cache_openstack_clnt_cmds[$service]#$word }% $word}/ $word } ]] && cmd=$word && break

You could get around the triple % # / check by adding a space before and
after the string, i.e., let the associative array's value be
    " foo bar baz "
and then just grep for " foo " (with the spaces).

Or you could use the (w) flag:
    % s="foo foobar"   
    % print -r -- $s[(wI)foo]
    % print -r -- $s[(wI)bar]

Or you could call use a different variable name for each command, i.e.,
«typeset -a _cache_openstack_magnum_subcommands» and so on.  You'd then
use the (P) parameter expansion flag to access the variable:
    typeset -a $cachevar
    print -rl -- ${(P)cachevar}
    compadd -a -- $cachevar

You may also need to change ${word} to ${(b)word} inside the condition
to prevent $word from being interpreted as a pattern.  I know I said
that [offlist] above virsh too, I haven't made the change there yet but
I think I will later.

> There's one case which I'm not sure there's a perfect solution without
> hard-coding / special-casing lots of commands/options: some commands
> of some clients accept some options more than once - for example, for
> "openstack project create" the "--property" option could be repeated
> (to provide several key=value pairs).

I'm not sure what's the problem here: whether it's needing to write code
to permit select options to be specified multiple times or having to
enumerate all options that may be multiply-specified.

If it's the former: _arguments solves that for you:
    _f() _arguments : '*-x:foo:_hosts'
    compdef _f f
    f -x bar -<TAB><TAB>

If it's the latter: the alternative to hardcoding a list would be to
parse that information from the --help or --completion output.  This may
mean getting openstack upstream to emit that information therein.

(Tangentially: I wish there were a standard format for parseable help;
basically a variation of --help that emitted information that
(a) were machine parseable, (b) could be compiled into a zsh completion

> So if trying to stay generic,
> we'd need to accept several options in all cases (which is mostly
> incorrect) or accept options only once and force the user to type
> the option if wanted more than once. I've chosen the latter as
> it would seem that in most cases there's some typing needed anyway
> for repetitive options (like key=value pairs, DNS servers, IP
> addresses, etc), so while not perfect this doesn't strike me too
> cumbersome.

> ---
>  Completion/Unix/Command/_openstack | 136 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 136 insertions(+)
>  create mode 100644 Completion/Unix/Command/_openstack

I'll go through the diff later.



Messages sorted by: Reverse Date, Date, Thread, Author