zsh-users
 help / Atom feed
* Possible to use _arguments with _regex_arguments?
@ 2019-09-18  2:31 Ronan Pigott
  2019-09-18 20:21 ` Ronan Pigott
  0 siblings, 1 reply; 5+ messages in thread
From: Ronan Pigott @ 2019-09-18  2:31 UTC (permalink / raw)
  To: zsh-users

Hello,

I've written a number of zsh completions recently and I find that
generally there are two patterns that work well, with _arguments using
->state to dispatch completions and _regex_arguments to build a regex
state machine.

Often I find that I'd like to use both _arguments and _regex_arguments
together, using _arguments to parse the opt_args and _regex_arguments to
handle the rest. I think it would have some advantages over building the
whole completion in _regex_arguments. _arguments already closely resembles
the behavior of getopt, consuming arguments it recognizes and leaving
the remainder in $line for dispatched functions to consider. It also
easily supports behavior where it ignores flags following a '--'
argument, which is not trivial to replicate with _regex_arguments.
Ideally, I think it would be possible to use _arguments to
define the flagged arguments I want to check and keep their values in
opt_args, but use a _regex_arguments function as an action for
_arguments acting on $line, like so:

```
_regex_arguments _myfunc ...
_arguments -S -s \
	{-o+,--option}'[An option]:tag:(some values)'
	'*:positional arguments:_myfunc'
```

However, in the above case, if _myfunc was not carefully crafted to ignore
'--option' it will fail to match and provide no completions because _myfunc
operates exclusively on $words. Is it possible to use _regex_arguments
functions on anything else, or in any other context?

One thing I thought to try was set '{words=("$line[@]"); _myfunc}' for
the action, but it did not seem to work.

If it cannot be done, is there another way that I can transform the line
to be completed before running (or re-running) the completion to make
this idea possible?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Possible to use _arguments with _regex_arguments?
  2019-09-18  2:31 Possible to use _arguments with _regex_arguments? Ronan Pigott
@ 2019-09-18 20:21 ` Ronan Pigott
  2019-09-18 21:07   ` Bart Schaefer
  2019-09-18 21:32   ` Oliver Kiddle
  0 siblings, 2 replies; 5+ messages in thread
From: Ronan Pigott @ 2019-09-18 20:21 UTC (permalink / raw)
  To: zsh-users

On Tue Sep 17, 2019 at 7:31 PM Ronan Pigott wrote:
> One thing I thought to try was set '{words=("$line[@]"); _myfunc}' for
> the action, but it did not seem to work.
> 
> If it cannot be done, is there another way that I can transform the line
> to be completed before running (or re-running) the completion to make
> this idea possible?

I've since found that _arguments itself has the ability to transform the
words and CURRENT special parameters by specifying the argument like:
'*::message:action', but unfortunately it still does not produce the
desired result when 'action' is a function generated by
_regex_arguments. Can anyone explain the behavior I see?

What I observe is that when _myfunc is created by _regex_arguments, and
the command argument is passed to _arguments like so: '*:message:_myfunc'

	`command arg1 arg2` is completed correctly as expected by _myfunc
	`command -o option arg1` is offered no completions by _myfunc, as it
	does not match.

When I use '*::message:_myfunc', completion is no longer tripped up by
options, but _myfunc always acts as if it is completing the first word
for all normal arguments, as if $words was empty and CURRENT=1 even if
there are many normal arguments. I'm looking for a way to have _myfunc
when invoked as an action of _arguments see only (and all of) the normal
arguments, but for some reason the _regex_arguments functions don't seem
to behave that way.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Possible to use _arguments with _regex_arguments?
  2019-09-18 20:21 ` Ronan Pigott
@ 2019-09-18 21:07   ` Bart Schaefer
  2019-09-18 21:36     ` Ronan Pigott
  2019-09-18 21:32   ` Oliver Kiddle
  1 sibling, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2019-09-18 21:07 UTC (permalink / raw)
  To: Ronan Pigott; +Cc: Zsh Users

On Wed, Sep 18, 2019 at 1:39 PM Ronan Pigott <rpigott314@gmail.com> wrote:
>
> When I use '*::message:_myfunc', completion is no longer tripped up by
> options, but _myfunc always acts as if it is completing the first word
> for all normal arguments, as if $words was empty and CURRENT=1 even if
> there are many normal arguments.

I'm not familiar with all the nuances of _regex_arguments, but my
impression from looking through a couple of the places where it is
used is that $words[1] always has to be the command name.  That is, it
always expects to parse a complete command line by catenating $words
back together, so you can't have shifted the command name itself off
the front before you invoke it.  You could probably get away with
shoving a dummy command word onto the front of $words, but I haven't
made any attempt to try it.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Possible to use _arguments with _regex_arguments?
  2019-09-18 20:21 ` Ronan Pigott
  2019-09-18 21:07   ` Bart Schaefer
@ 2019-09-18 21:32   ` Oliver Kiddle
  1 sibling, 0 replies; 5+ messages in thread
From: Oliver Kiddle @ 2019-09-18 21:32 UTC (permalink / raw)
  To: Ronan Pigott; +Cc: zsh-users

"Ronan Pigott" wrote:
> I've since found that _arguments itself has the ability to transform the
> words and CURRENT special parameters by specifying the argument like:
> '*::message:action', but unfortunately it still does not produce the
> desired result when 'action' is a function generated by
> _regex_arguments. Can anyone explain the behavior I see?

Both _arguments and _regex_arguments like the words array to start with
an initial element for the command. With '*:message:action', the -o
options get left in $words. With the '*::... form, they are stripped but
there is no initial element left. Try using
    '*::positional arguments:= _myfunc'

More specifically:

  _regex_arguments _myfunc /$'*\0[ \t\n]#'/ \
    '/[]/' ':args:arg:(one two three)'

  _arguments -S -s \
    {-o+,--option}'[an option]:tag:(some values)' \
    '*::positional arguments:= _myfunc'

The = causes it to add back an initial element in $words.
_regex_arguments is then ignoring this with the /$'*\0[ \t\n]#'/ pattern
so this is all fairly pointless but _regex_arguments was somehow
designed for handling the whole command-line.

If you'd like to see a real example that combines _arguments with
_regex_arguments see _sed from a relatively recent zsh. 

Oliver

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Possible to use _arguments with _regex_arguments?
  2019-09-18 21:07   ` Bart Schaefer
@ 2019-09-18 21:36     ` Ronan Pigott
  0 siblings, 0 replies; 5+ messages in thread
From: Ronan Pigott @ 2019-09-18 21:36 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Wed Sep 18, 2019 at 2:07 PM Bart Schaefer wrote:
> On Wed, Sep 18, 2019 at 1:39 PM Ronan Pigott <rpigott314@gmail.com> wrote:
> >
> > When I use '*::message:_myfunc', completion is no longer tripped up by
> > options, but _myfunc always acts as if it is completing the first word
> > for all normal arguments, as if $words was empty and CURRENT=1 even if
> > there are many normal arguments.
> 
> You could probably get away with shoving a dummy command word onto the
> front of $words, but I haven't made any attempt to try it.

Brilliant! I think that was it! If I allow the regex to match any string
as the command word, I can now specify the action as '*::message:= _myfunc'
and it appears to work great! Thank you!

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-18  2:31 Possible to use _arguments with _regex_arguments? Ronan Pigott
2019-09-18 20:21 ` Ronan Pigott
2019-09-18 21:07   ` Bart Schaefer
2019-09-18 21:36     ` Ronan Pigott
2019-09-18 21:32   ` Oliver Kiddle

zsh-users

Archives are clonable: git clone --mirror http://inbox.vuxu.org/zsh-users

Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.users


AGPL code for this site: git clone https://public-inbox.org/ public-inbox