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

Re: _arguments not works as expected. Bug?

On 26.09.2014 13:02, Bart Schaefer wrote:
> 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
> completions.
> 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.

Thanks for detailed clarification. I see all complications, but also I see that very powerful
_arguments function looks slightly «incompleted» itself. Lot of people used only «basic» _arguments'
functionality – maybe because of lack of consistency in «extended» functional. Maybe  this
inconsistency is not «important enough» because of hard to use?

For instance, I tried to implement simple scenario:
command have a couple of «common» options: -a and -b; a few of mutually exclusive options: -k,-l,-m;
and a -h option that could be used only alone. Exclusion sets are not nested, so I can't implement
logic as «-h or (-a,-b (-k or -l or -m))». I can use prepending exclusion lists, but they aren't
worked with -s so I have to deny multi-option words though exclusions sets do their work even in
multi-option words. Very pity.

As a result, I failed to implement proper completion logic and forced to fallback to «simple» way –
all options in one heap. In my opinion, full absence of «exclusion» logic is better that *partial*
implementation because it is more predictable for user.

Sorry for my English :)

  Vasiliy Ivanov <beelzebubbie.logs@xxxxxxxxx>

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