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

Re: ordering of file-patterns completions

On 11/6/13, 9:17 PM, Bart Schaefer wrote:
On Nov 6,  6:11pm, John wrote:
} > doesn't quite generalize if there may be options (words starting with
} > a hyphen) between the command name and the first file.  If that is the
} > case, you'll need to do some pre-processing of $words before calling
} > _arguments to determine which position to reference instead of [2].
} Yeah, unfortunately I do.  I was using _arguments to process those, and
} then zstyle to deal with the files.  But I'm not quite understanding how
} to do what you're describing to pre-process them instead of using
} _arguments.

How complicated this needs to be depends on what might appear in the
words preceding the first file.

If there's nothing but options, for example, then you can probably do:

   local first_file=$(( ${words[(I)-*]} + 1 ))

which says to start from the end of the array and look backward to
find the index of the first word that DOES start with a hyphen, and
then add one to it.  Or, if there might be file names that start with
hyphen, then:

   local first_file=$(( ${${words[2,-1]}[(i)[^-]*]} + 1 ))

which says "in the array formed by the second through last elements of
the words array, report the index of the first element that does not
begin with a hyphen" and then add one to compensate for starting at 2.

The first one nearly does it, but seems to be confused when there are no options at all. That is, it works fine as long as there is a --opt1, but if there isn't, the *: portion says it's completing the right thing, but then lists all the files rather than the matching one:

% yes <tab>XXX.<tab>
Completing XXX file
XXX.0       XXX.bogus   XXX.bogus3
XXX.1       XXX.bogus2  XXX.bogus4

% yes --opt1 XXX.0 <tab>XXX-YYY.0

% yes XXX.0 XXX<tab>
Completing XXX extra files
XXX-YYY.0   XXX.0       XXX.bogus XXX.bogus3
XXX-YYY.1   XXX.1       XXX.bogus2  XXX.bogus4

This is with:

#compdef yes

local first_file=$(( ${words[(I)--*]} + 1 ))

_arguments \
        '--opt1[desc1]' \
        '--opt2[desc2]' \
        '1:XXX file:_files -g "*XXX.*"' \
        '*:XXX extra files:_files -g "*XXX-*.${words[first_file]:e}"'

I ended up adding:

if [[ $first_file -lt 2 ]]; then

And that fixed it. Not realizing that the array was 1-based threw me for a bit. I also changed the :x to a :e, as :x just gave me an error, and :e matched the description of what I think you had meant.


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