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

Re: _arguments optspecs (was Re: Editing the history in the shell)

Bart Schaefer wrote:
> zed -f _zed -x2
> is not accepted by zed itself.

Yes, -f changes the interpretation of the normal arguments rather than
taking an argument itself. I assume that's also true for the new -h.

> > ... I try to avoid leaving the
> > number out for any spec that is the target of an exclusion.
> Do I understand, then, that you would have written the original
>         '(- 2):file:_files' \
>         '(1):shell function:_functions'
> as
>         '(- 2)1:file:_files' \
>         '(1)2:shell function:_functions'
> ??  I can see where that might have puzzled me less.

Yes, exactly.

> > > The second spec offers -h followed by "history file" as the argument
> > > to -h, and won't offer -f or -x or a first non-option argument.
> >
> > Yes. And in excluding the first non-option argument, it will move on and
> > offer the second one in the first position. So you get "history size" in
> > position 1 despite it being labelled as 2.
> OK, that explains my confusion then.  Why does it do that?  If I
> wanted to indicate that _arguments was NOT meant to "move on and offer
> the second one in the first position", would I have to write
>         '(1)2:history file: '
> ??  Or is there a way to say "exactly the Nth position" without also
> specifying the (N-1)th position?

I don't think that's possible. And in practical reality, I don't think
it would be especially useful. I guess the answer to why it does that is
because it is useful.

Note that exclusions apply to later arguments only so excluding (1) from
2:history␣file is meaningless.

> > I can't find any arrangement of words on a command-line that gives the
> > argument after -h as being anything other than "history file". Neither
> > is it being counted as one of the non-option arguments.
> "count the argument after -h as a non-option argument" and "offer the
> second one in the first position" have equivalent results from the
> point of view of a black-box test.  I just didn't know how to explain
> what I was seeing.

Yes, I can see that would be the case. The tag (as indicated by
_complete_help) will be different, however.

> > There's a list of possible states. In each state, individual specs
> > are disabled if an option is found which would disable it. If you
> > exclude positional arguments, subsequent ones become active at an
> > earlier position.
> Is that "subsequent" part stated in the doc anywhere that you can point to?

No. The only reference to putting numbers in the exclusion lists at all
is an example giving `(-two -three 1)`.

> >         '(-h 1 3 4)-f[edit function]' \
> >         '(-h 1 3 4)-x+[specify spaces to use for indentation in function expansion]:spaces' \
> >         '(-f -x 1 2)-h[edit history]' \
> >         '(- 2 3 4)1:file:_files' \
> >         '(3 4)2:shell function:_functions' \
> >         '3:history file:_files' \
> >         '4:history size';;
> I would never have thought of that, because without the implicit
> "become active earlier" there is no third or fourth position.
> Perhaps the way to explain/understand this is that "position" here
> does not mean "position on the command line", rather it means "order
> in which to attempt to fill the next available position on the command
> line".

Yes, regarding the numbers as a priority for ordering may be a good way
to explain this in the documentation.

The exception to this is if you specify them upfront with a gap:
  _arguments '5:five'
that'll complete nothing in positions 1-4 which is fairly useless.
This might be regarded at least as being undefined behaviour and perhaps
as a bug.

The documentation could also be clearer for the case where the number is
omitted. It is allocated by simply incrementing the number from the most
recent one. Note:-
  _arguments '5:five' '2:two' ':three' '3:trois'
results in:
  _arguments:comparguments:325: doubled argument definition: 3:trois

> One other thing ...

> On Mon, May 25, 2020 at 10:29 AM Oliver Kiddle <okiddle@xxxxxxxxxxx> wrote:
> >
> >         '4:history size';;

> Doc says:

>      The forms for ACTION are as follows.

>       (single unquoted space)
>           This is useful where an argument is required but it is not
>           possible or desirable to generate matches for it.  The MESSAGE
>           will be displayed but no completions listed.  Note that even
>           in this case the colon at the end of the MESSAGE is needed; it
>           may only be omitted when neither a MESSAGE nor an ACTION is
>           given.

> That seems to imply that you can write "4:" or "4:history size: " but
> not what you did write.  Is the doc wrong?

That was introduced in workers/11554 and I'm fairly certain it is wrong.
As a hunch, the _arguments source was followed when listing the possible
action forms and the subtlety that the empty string matches in the
following line (411) was overlooked:

  if [[ "$action" = \ # ]]; then

For what it's worth, I tend to leave the action out (going back to
before that documentation change) because it keeps the spec a tiny bit
shorter. And all too often _arguments specs are rather too long.


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