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

Re: Problem with _arguments



On 11/22/06, Peter Stephenson <pws@xxxxxxx> wrote:

> Actually, would there be a good way of tricking _arguments into only
> seeing what you want it to see?  In this case, it would work fine if
> one could trick it into only seeing the stuff after src, so that it
> would continue completing options.

There are certainly ways of updating the line, but the trouble is to
find out what you need to do either you're going to be doing some
parsing yourself or running _arguments twice.  You can edit words (the
command line) and CURRENT (the index into it), plus it's also possible
in some contexts to tell _arguments to limit the words visible in the
completion that it's calling by the use of enough colons.  I find
directly manipulating words and CURRENT less infuriating.

This worked out quite well actually.  Find is actually incredibly
complicated and has a rather horrible interface.  Anyway, here's my
solution:

   integer i
   (( i = index_of_find + 1 ))
   while [[ $words[i] == -([HLP]|-(help|version)) ]]; do
     (( i++ ))
   done
   while [[ -d $words[i] ]]; do
     (( i++ ))
   done
   words=($words[1,index_of_find] $words[i,-1])
   (( CURRENT -= i - index_of_find - 1 ))
   integer old_words_length
   (( old_words_length = $#words ))
   words=(${words:#\\[()\!]})
   (( CURRENT -= old_words_length - $#words ))

Index_of_find keeps track of the index of -find in the words array.
Here's the algorithm:

1.  The option -find can be followed by the options -H, -L, or -P to
specify how symbolic links are to be dealt with, along with -help or
-version, so skip those. [1]

2.  After that, any number of directories may follow. [2]

3.  Now we know what slice to remove from the words array and we do so.

4.  Next we need to remove any \!, any \(, and any \) that may appear
in the $words array, as these are used to negate and group expressions
and also mess up the command-line processing of _arguments. [3]

/Now/ we can call _arguments.

This can actually be used in _find as well, and I might submit a patch
once I'm done with this completion definition (for mkisofs if that was
unclear).

Super-happy-fun-thank-yous to Peter and Bart for your suggestions on
how to solve this.  Your answers are always helpful, insightful, and
to the point.  Seriously, you guys rock.  But it's also a bit sad that
you seem to be the only two that posses the necessary knowledge of Zsh
to answer these questions (and are active on these two mailing lists).
I hope my shell-skills will reach your level some day.

 super-happy-fun-time-nikolai

[1]  Of course, if -help or -version is in the command line,
completion has ended already (they're defined as '(- *)-help...' and
'(- *)-version...'), so this is superfluous, but at least it's
complete.

[2]  Checking that they're directories is also a bit stupid, and
should perhaps only check that they don't match an option, for
example, [^-]*, but I figured this was a bit more expressive.

[3]  This could technically be limited to only the slice [i,-1], but I
wanted to keep things simple.



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