From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11895 invoked by alias); 26 Sep 2014 07:02:23 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 33250 Received: (qmail 20698 invoked from network); 26 Sep 2014 07:02:11 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <140926000210.ZM30825@torch.brasslantern.com> Date: Fri, 26 Sep 2014 00:02:10 -0700 In-reply-to: <54244804.8080305@gmail.com> Comments: In reply to Vasiliy Ivanov "_arguments not works as expected. Bug?" (Sep 25, 10:51pm) References: <54244804.8080305@gmail.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: _arguments not works as expected. Bug? Cc: Vasiliy Ivanov MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Sep 25, 10:51pm, Vasiliy Ivanov wrote: } } % testcmd -q producing only -q completion as expected (as -q excludes only -v), but: } % testcmd -q 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.