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

completion utility functions that take options generally do not work



Using the word "generally" in the mathematical sense, eg, I have
examples of ones that don't work :).
When you call a utility function from _arguments, like this (this is a
bad example, it's only used on IRIX):
      '-b[mount all filesystems in /etc/fstab except those
listed]:mount point:_dir_list -s,'
_arguments helpfully adds some compadd options to the argument list
for you to pass on to compadd "$@". However, it adds these between the
first word and the rest of the words, so the resulting command would
be something like _dir_list -J mygroup -1 -s or so. Here's how
_dir_list parses its options:
while [[ "$1" = -(s*|S) ]]; do

Here's how _command_names -e works:
if [[ "$1" = -e ]]; then

This works as well as you might expect, but you can try this yourself with:
% myfunction() {}
% zmv -p myfun<tab>
and notice it will happily complete myfunction which will not work,
because it is not an external command, even though _zmv dutifully
does:
  '(-M -C -L -s)-p+[specify program to run instead of cp, ln or
mv]:program:_command_names -e' \

If you copy the -b line to your current system's argument array in
_mount, you'll notice that it will complete directories separated by
colons (the default), rather than the specified comma.

If you add a space after the colon in your _arguments spec, then it
will not add the compadd options, and the argument parsing in the
utility function will work. But since it doesn't add the compadd
options, the compadd calls will obviously pass on an empty "$@", this
would also not be great, plus we'll never get anyone to remember to
add this space.

I'm not sure if there's an obvious solution here, unfortunately. We
could go through all the utility functions and at least use zparseopts
instead of checking $1, but this will still stop working if _arguments
ever wants to pass on more options to compadd and they collide with
whatever options the utility functions use. I think the current set of
options that can be added is (-J -X -V -F -x -M -n -2 -1) (documented
under the entry for _guard for some reason), is this specified as
being the only ones we will ever pass on like this? If all the utility
functions used long options, this wouldn't be a problem, but obviously
we already have many that use short options.

I skimmed through the utility functions in the manpage, a few hilights below.

_numbers seems to have very carefully avoided the above set of
options, and uses zparseopts, so it works correctly. I guess that the
path forward is to convert the utility functions to use zparseopts,
and in the case of ones that use the forbidden ones, we'll change
them?

_sequence does unfortunately use -n while also saying it will pass on
common compadd options to compadd.
% zstyle ':completion:*:*:flurg:*' hidden true # this adds -n to the
options _description adds to your compadd calls
% compdef -e '_arguments "-f: :_sequence _files"' flurg
% flurg<tab>zsh: command not found: m:{a-z}={A-Z}
not ideal. the zparseopts call in _sequence will remove the -n and its
argument (-M), leaving just the matcher spec on its own.

_email_addresses also uses -n,
% zstyle ':completion:*:*:mutt:*' hidden true
% mutt <tab>
%B----\ recipient%b
%B----\ user%b
-
-J
-M
-X
-k
-n
[actual list of email addresses follow, which i am not going to include here]

-- 
Mikael Magnusson




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