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

Re: _arguments not works as expected. Bug?

On Sep 25, 10:51pm, Vasiliy Ivanov wrote:
} % testcmd -q <tab> producing only -q completion as expected (as -q excludes only -v), but:
} % testcmd -q<tab> offered both -q and -v (why?)

As you might expect, it has to do with the implementation of -s and
the way completion always operates on a single word.

In order to complete from "x" to "xy" or "xyz", compadd has to be told
the set of all full words that might appear in that position.  It then
filters out the words that don't match.

Because of this, when you use "_arguments -s" and the context is the
middle of a word that appears to be multiple single letters, the words
passed to compadd have to be constructed by pasting together letters
from the set of all possible single letter arguments.  Thus if there
are single letter options -m, -n, and -o, and -m already appears, then
_arguments constructs the words -mm (if -m is repeatable), -mn, and
-mo, and passes those to compadd, because those are all the possible
words that begin with -m in that context. [*]

The complication is that it is the script that constructs -mn and -mo,
but the "exclusion list" definition is parsed by the "comparguments"
builtin and isn't available to the script; instead it's applied by
the internals when "compadd" is finally called.  So the script does
not "know" that it could drop some of those letters when generating
the possible permutations; it just generates all of them.

Down in compadd, the exclusion list operates on full words, not on
substrings.  (-v)-q doesn't mean to exclude "v" from words beginning
with "-" of which it is a substring, it means to exclude the word
"-v".  Since the words passed to compadd in this example are "-qq"
and "-qv", neither matches "-v" and so both are offered as valid

So now you have the answer to "why?".  Preventing it from happening
would require new C code (another option to "comparguments" perhaps?)
and/or some hairy script work to explode the word on the line out to
its individual letters, filter them, and glue them back together.

The particular feature of having exlusions work on multiple options
packed into the same word has not so far been considered important
enough to attract anyone willing to do that work.

[*] It would also work for it to ignore the fact that -m is already on
the line and generate -no, -om, etc., and allow comparison to the word
on the line to filter out the ones not starting with -m, but it tries
to do a small amount of optimization.

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