zsh-users
 help / color / mirror / Atom feed
* completion within a function
@ 2020-12-29 15:24 Ray Andrews
  2020-12-29 18:52 ` Bart Schaefer
  0 siblings, 1 reply; 40+ messages in thread
From: Ray Andrews @ 2020-12-29 15:24 UTC (permalink / raw)
  To: Zsh Users

How do we execute a completion within a function?



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

* Re: completion within a function
  2020-12-29 15:24 completion within a function Ray Andrews
@ 2020-12-29 18:52 ` Bart Schaefer
  2020-12-29 19:36   ` Felipe Contreras
  2020-12-29 21:04   ` Ray Andrews
  0 siblings, 2 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-29 18:52 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Tue, Dec 29, 2020 at 7:24 AM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> How do we execute a completion within a function?

Depends on the context.

If the function is already executing as a ZLE widget, it might invoke
"zle recursive-edit".

If it's running as a command or from inside a script, using "vared" to
read from the keyboard into a local is one way.

There are examples of both of these in the Functions tree in the distribution.


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

* Re: completion within a function
  2020-12-29 18:52 ` Bart Schaefer
@ 2020-12-29 19:36   ` Felipe Contreras
  2020-12-29 19:41     ` Roman Perepelitsa
  2020-12-29 21:04   ` Ray Andrews
  1 sibling, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2020-12-29 19:36 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Ray Andrews, Zsh Users

On Tue, Dec 29, 2020 at 12:53 PM Bart Schaefer
<schaefer@brasslantern.com> wrote:
> On Tue, Dec 29, 2020 at 7:24 AM Ray Andrews <rayandrews@eastlink.ca> wrote:

> > How do we execute a completion within a function?
>
> Depends on the context.

I presume Ray wants something like "complete ma", which would return
"make man ..." essentially everything that typing "ma<tab>" would
return.

-- 
Felipe Contreras


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

* Re: completion within a function
  2020-12-29 19:36   ` Felipe Contreras
@ 2020-12-29 19:41     ` Roman Perepelitsa
  0 siblings, 0 replies; 40+ messages in thread
From: Roman Perepelitsa @ 2020-12-29 19:41 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Bart Schaefer, Ray Andrews, Zsh Users

On Tue, Dec 29, 2020 at 8:36 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Tue, Dec 29, 2020 at 12:53 PM Bart Schaefer
> <schaefer@brasslantern.com> wrote:
> > On Tue, Dec 29, 2020 at 7:24 AM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> > > How do we execute a completion within a function?
> >
> > Depends on the context.
>
> I presume Ray wants something like "complete ma", which would return
> "make man ..." essentially everything that typing "ma<tab>" would
> return.

Could be. Or a handful of other plausible interpretations. "Execute a
completion within a function" is more of a rorschach test than a
problem statement.

Ray, what are you trying to achieve?

Roman.


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

* Re: completion within a function
  2020-12-29 18:52 ` Bart Schaefer
  2020-12-29 19:36   ` Felipe Contreras
@ 2020-12-29 21:04   ` Ray Andrews
  2020-12-29 21:21     ` Ray Andrews
  2020-12-29 21:48     ` Bart Schaefer
  1 sibling, 2 replies; 40+ messages in thread
From: Ray Andrews @ 2020-12-29 21:04 UTC (permalink / raw)
  To: zsh-users

On 2020-12-29 10:52 a.m., Bart Schaefer wrote:
> On Tue, Dec 29, 2020 at 7:24 AM Ray Andrews <rayandrews@eastlink.ca> wrote:
>> How do we execute a completion within a function?
> Depends on the context.
>
> If the function is already executing as a ZLE widget, it might invoke
> "zle recursive-edit".
>
> If it's running as a command or from inside a script, using "vared" to
> read from the keyboard into a local is one way.
>
> There are examples of both of these in the Functions tree in the distribution.
>
I'm looking for something as simple as this:

func ()
{
code
     cd $1 [TAB]
code
code
}

... so that I can automatically execute a completion within a function.  
'vared' is a variable editor no?  Does it do more than I think?  Even 
tho I've turned off all 'smart' expansion here, what would be cool is to 
have it expand only directories and I'm betting I can zoom in on the 
exact code to do that.



I presume Ray wants something like "complete ma", which would return
"make man ..." essentially everything that typing "ma<tab>" would
return.

Yeah, just that Filipe.




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

* Re: completion within a function
  2020-12-29 21:04   ` Ray Andrews
@ 2020-12-29 21:21     ` Ray Andrews
  2020-12-29 22:03       ` Bart Schaefer
  2020-12-29 21:48     ` Bart Schaefer
  1 sibling, 1 reply; 40+ messages in thread
From: Ray Andrews @ 2020-12-29 21:21 UTC (permalink / raw)
  To: zsh-users

On 2020-12-29 1:04 p.m., Ray Andrews wrote:
>
>
> I presume Ray wants something like "complete ma", which would return
> "make man ..." essentially everything that typing "ma<tab>" would
> return.
>
> Yeah, just that Filipe.
>
>
This snippet pretty well does it, mind I'm still interested in trying to 
use completion:
>     {
>         local dirs=( $1*(N) )
>
>         for ((aa = 1; aa <= $#dirs; aa++)); do
>             ! [ -d "$dirs[$aa]" ] && dirs[$aa]=''
>         done
>
>         dirs=($dirs) #How do folks survive who don't know this?
>         [ "$#dirs" -eq 1 ] && cd "$dirs[1]"
>         # else, fall through to n_list():
>     }
>



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

* Re: completion within a function
  2020-12-29 21:04   ` Ray Andrews
  2020-12-29 21:21     ` Ray Andrews
@ 2020-12-29 21:48     ` Bart Schaefer
  2020-12-30  0:31       ` Ray Andrews
  1 sibling, 1 reply; 40+ messages in thread
From: Bart Schaefer @ 2020-12-29 21:48 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Tue, Dec 29, 2020 at 1:04 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> func ()
> {
> code
>      cd $1 [TAB]
> code
> code
> }
>
> ... so that I can automatically execute a completion within a function.

Where does the TAB come from?

I think what you're actually asking is how to apply the contextual
completion "rules" defined for a command ("cd" in this case) to a
parameter expansion.  There really is not any way to do that
"automatically" because completion is tightly bound to having the ZLE
line editor active.  It could be done the way that the test suite
emulates completion, but that's exceptionally convoluted, especially
error handling.

> 'vared' is a variable editor no?  Does it do more than I think?

If you were to write

func()
{
  code
    vared 1
    cd $1
  code
  code
}

Then at the point vared is invoked, func would pause, wait for the
user to press TAB or whatever, and then after accept-line is executed,
continue with whatever result.

Yes, you actually can vared the positional parameters.

More in response to the next message.


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

* Re: completion within a function
  2020-12-29 21:21     ` Ray Andrews
@ 2020-12-29 22:03       ` Bart Schaefer
  0 siblings, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-29 22:03 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Tue, Dec 29, 2020 at 1:21 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> This snippet pretty well does it, mind I'm still interested in trying to
> use completion:
> >     {
> >         local dirs=( $1*(N) )

You don't need completion for that.

  local dirs=( $1*(-/N) )
  [[ $#dirs -eq 1 ]] && [[ -d $dirs[1] ]] && cd "$dirs[1]"
  # else, fall through to n_list():

will do everything your example is doing.  (-) means follow symlinks
if there are any, and (/) means the result must be a directory.

With extendedglob set, file expansion (globbing) can do
case-insensitive matching and approximate matching as well.

> >         for ((aa = 1; aa <= $#dirs; aa++)); do
> >             ! [ -d "$dirs[$aa]" ] && dirs[$aa]=''
> >         done

If you must do it in a loop for some reason:

  for ((aa = 1; aa <= $#dirs; )); do
    if [[ -d $dirs[aa] ]]; then ((aa++))
    else dirs[aa]=()
    fi
  done

Then you don't need dirs=($dirs) later.


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

* Re: completion within a function
  2020-12-29 21:48     ` Bart Schaefer
@ 2020-12-30  0:31       ` Ray Andrews
  2020-12-30  4:34         ` Roman Perepelitsa
  2020-12-30  6:45         ` Bart Schaefer
  0 siblings, 2 replies; 40+ messages in thread
From: Ray Andrews @ 2020-12-30  0:31 UTC (permalink / raw)
  To: zsh-users

On 2020-12-29 1:48 p.m., Bart Schaefer wrote:
>
>> func ()
>> {
>> code
>>       cd $1 [TAB]
>> code
>> code
>> }
>>
>> ... so that I can automatically execute a completion within a function.
> Where does the TAB come from?

That's what I'm asking.  How could I simulate the effect of completing 
on $1 within the function automatically?  Or perhaps:

     new_var=$( complete_it $1 )

where 'complete _it' is a function that does just what TAB would do on 
the command line.



>
> I think what you're actually asking is how to apply the contextual
> completion "rules" defined for a command ("cd" in this case) to a
> parameter expansion.  There really is not any way to do that
> "automatically" because completion is tightly bound to having the ZLE
> line editor active.  It could be done the way that the test suite
> emulates completion, but that's exceptionally convoluted, especially
> error handling.
Geez, I'd have thought that it would just be a question of digging up 
the right completer.  But as you say.
> 'vared' is a variable editor no?  Does it do more than I think?
> If you were to write
>
> func()
> {
>    code
>      vared 1
>      cd $1
>    code
>    code
> }
>
> Then at the point vared is invoked, func would pause, wait for the
> user to press TAB or whatever, and then after accept-line is executed,
> continue with whatever result.
Cool.  That's bound to be useful even if not right now.  I had no idea 
it could be used within a function like that.

NEXT MSG:

   local dirs=( $1*(-/N) )

Marvelous.  If I was 20 I'd devote the next 10 years to reading the manual and have the health to survive it.  The thing is that zsh code is so terse that you can't go searching for answers unless you already know where to look. Anyway, that line of yours does it all exactly as I want.  Thanks Bart.




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

* Re: completion within a function
  2020-12-30  0:31       ` Ray Andrews
@ 2020-12-30  4:34         ` Roman Perepelitsa
  2020-12-30 16:45           ` Ray Andrews
  2020-12-30  6:45         ` Bart Schaefer
  1 sibling, 1 reply; 40+ messages in thread
From: Roman Perepelitsa @ 2020-12-30  4:34 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Wed, Dec 30, 2020 at 1:44 AM Ray Andrews <rayandrews@eastlink.ca> wrote:
>  How could I simulate the effect of completing
> on $1 within the function automatically?  Or perhaps:
>
>      new_var=$( complete_it $1 )
>
> where 'complete_it' is a function that does just what TAB would do on
> the command line.

Where and how do you want to invoke this code? From a non-interactive
script? From an interactive shell by pressing a key combination?
Something else?

If there are several possible completions, should comple_it return all
of them? Show a completion menu? Fail? Something else?

Should complete_it respect all completion options and zstyle definitions?

It would help if you can describe what you want to achieve from the
user's point of view with as little presumption of implementation as
possible.

Roman.


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

* Re: completion within a function
  2020-12-30  0:31       ` Ray Andrews
  2020-12-30  4:34         ` Roman Perepelitsa
@ 2020-12-30  6:45         ` Bart Schaefer
  1 sibling, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-30  6:45 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Tue, Dec 29, 2020 at 4:32 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
>      new_var=$( complete_it $1 )
>
> where 'complete _it' is a function that does just what TAB would do on
> the command line.

Along with what Roman said ... where does the context come from?

That is, if you were completing (the string represented by) $1 on the
command line, you have the whole rest of the line, or at least
everything preceding it, to establish how the input should be
interpreted.  So it can't be as simple as passing a single word as
argument.


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

* Re: completion within a function
  2020-12-30  4:34         ` Roman Perepelitsa
@ 2020-12-30 16:45           ` Ray Andrews
  2020-12-30 17:21             ` Felipe Contreras
  0 siblings, 1 reply; 40+ messages in thread
From: Ray Andrews @ 2020-12-30 16:45 UTC (permalink / raw)
  To: zsh-users

On 2020-12-29 8:34 p.m., Roman Perepelitsa wrote:
>
> Where and how do you want to invoke this code?
In a function named 'c'.  It's my one stop shopping wrapper around 
'cd'.  Mostly it offers a zcurses based (thanks Sebastian) selection of 
previously visited directories from a persistent, global directory stack 
, but the code I just added (thanks Bart) now gives me this pseudo 
completion like this:

     8 /aWorking/Zsh/Source/Wk 4 $ c N-  # I could have just pressed TAB 
here to complete.
     Changing to N-functionsWorking ...

     8 /aWorking/Zsh/Source/Wk/N-functionsWorking 4 
$                              7:25AM Wed 30

... So before offering a zcurses selection from the directory stack, it 
now attempts what would be almost exactly the same as:

     $ cd N- [TAB]

... Bart's code just globs " N-* " so " N-functionsWorking " is found 
automagically.  It's sorta better than TAB anyway because there will be 
no mysterious completions.  Also actually using TAB on the command line 
sometimes gives you several possible completions but as I have it, if 
there's only one match it just 'cd's' there, if not, you get the zcurses 
selection window.  (And of course I still can complete using TAB if I 
feel like it anyway, that option remains.)  I quite love my 'c' wrapper, 
life was solitary, poor, nasty brutish and short without it.

So the idea of invoking completion within a function is now a matter of 
curiosity  only.  Still I'm surprised it can't be done.  It's one of 
those things where zsh smartness is hard to turn off.

Here's a real life example of 'c' being elegant.  Where the hell are my 
zsh distribution functions?

    8 /aWorking/Zsh/Source/Wk 4 $ c ,a Functions zsh
    Searching entire system for directories matching:  "Functions" "zsh"
    (case INsensitive, WILD) ...
    Changing to /aWorking/Zsh/Zsh-5.8/share/zsh/5.8/functions ...

    8 /aWorking/Zsh/Zsh-5.8/share/zsh/5.8/functions 4 $   # Sweetly found.






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

* Re: completion within a function
  2020-12-30 16:45           ` Ray Andrews
@ 2020-12-30 17:21             ` Felipe Contreras
  2020-12-30 20:43               ` Bart Schaefer
  0 siblings, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2020-12-30 17:21 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Wed, Dec 30, 2020 at 10:45 AM Ray Andrews <rayandrews@eastlink.ca> wrote:

> So the idea of invoking completion within a function is now a matter of
> curiosity  only.  Still I'm surprised it can't be done.  It's one of
> those things where zsh smartness is hard to turn off.

I can be done, it's just not straight-forward.

After removing all the unnecessary stuff from the tests, I came up
with this script that does list completions:

  ./complete "git --"

#!/bin/zsh

zmodload zsh/zpty

dir=$(mktemp -d)

cat > "$dir/.zshrc" <<'EOF'
setopt zle
setopt list_rows_first

LC_ALL=C
PS1="<PROMPT>"
TERM=dumb
fpath=($ZDOTDIR $fpath)
LISTMAX=1000 # There seems to be a bug in zsh with several thousands

autoload -U compinit && compinit -u

zstyle ":completion:*:default" list-colors "no=<NO>" "fi=<NO>"
"di=<NO>" "sp=<SP>" "lc=<LC>" "rc=<RC>" "ec=<EC>\n"
zstyle ':completion:*' verbose no

zle_complete () {
zle list-choices
zle kill-whole-line
print "<END-CHOICES>"
}
zle -N zle_complete
bindkey "^I" zle_complete
EOF

zpty zsh "ZDOTDIR=$dir zsh"
zpty -n -w zsh "$1"$'\t'
zpty -r zsh log '*<END-CHOICES>'

for x in ${(M)${(f)log}:#*'<LC><NO>'*}; do
print -- "${${x%'<EC>'*}#*'<RC>'}"
done

rm -r "$dir"

-- 
Felipe Contreras


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

* Re: completion within a function
  2020-12-30 17:21             ` Felipe Contreras
@ 2020-12-30 20:43               ` Bart Schaefer
  2020-12-30 20:46                 ` Bart Schaefer
                                   ` (3 more replies)
  0 siblings, 4 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-30 20:43 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 9:22 AM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> After removing all the unnecessary stuff from the tests, I came up
> with this script that does list completions:

I think it might be possible to do something even less complicated.
The basic idea is to first borrow this from the manual:

  zle -C all-matches complete-word _generic
  bindkey '^Xa' all-matches
  zstyle ':completion:all-matches::::' completer \
                 _all_matches _complete
  zstyle ':completion:all-matches:*' insert true

And then:

  do-complete() { zle -U $'\Cxa\n' }
  zle -N do-complete
  run-complete () {
    vared -i do-complete argv
  }
  complete() {
    local -i n=$argc
    zpty complete-tty run-complete "$@"
    zpty -r complete-tty
    zpty -d complete-tty
  }

There is likely some additional quoting needed on $@ to assure the
right arguments are passed to run-complete, and some more could be
done to separate the context from the results.


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

* Re: completion within a function
  2020-12-30 20:43               ` Bart Schaefer
@ 2020-12-30 20:46                 ` Bart Schaefer
  2020-12-30 20:50                 ` Ray Andrews
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-30 20:46 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 12:43 PM Bart Schaefer
<schaefer@brasslantern.com> wrote:
>
>   complete() {
>     local -i n=$argc
>     zpty complete-tty run-complete "$@"
>     zpty -r complete-tty
>     zpty -d complete-tty
>   }
>
> [...] some more could be
> done to separate the context from the results.

I started on that (hence n=$argc) but ran out of time.


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

* Re: completion within a function
  2020-12-30 20:43               ` Bart Schaefer
  2020-12-30 20:46                 ` Bart Schaefer
@ 2020-12-30 20:50                 ` Ray Andrews
  2020-12-30 21:31                 ` Roman Perepelitsa
  2020-12-30 22:18                 ` Felipe Contreras
  3 siblings, 0 replies; 40+ messages in thread
From: Ray Andrews @ 2020-12-30 20:50 UTC (permalink / raw)
  To: zsh-users

On 2020-12-30 12:43 p.m., Bart Schaefer wrote:
> I think it might be possible to do something even less complicated. 
I'll follow with interest if you guys pursue that but it's a master 
class for me in any case -- way above my head.  Could be a cool thing to 
be able to do tho.




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

* Re: completion within a function
  2020-12-30 20:43               ` Bart Schaefer
  2020-12-30 20:46                 ` Bart Schaefer
  2020-12-30 20:50                 ` Ray Andrews
@ 2020-12-30 21:31                 ` Roman Perepelitsa
  2020-12-30 22:05                   ` Bart Schaefer
  2020-12-30 22:18                 ` Felipe Contreras
  3 siblings, 1 reply; 40+ messages in thread
From: Roman Perepelitsa @ 2020-12-30 21:31 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Felipe Contreras, Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 9:44 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Dec 30, 2020 at 9:22 AM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > After removing all the unnecessary stuff from the tests, I came up
> > with this script that does list completions:
>
> I think it might be possible to do something even less complicated.

It's also possible to capture completions without IPC (via zpty or
otherwise). It's faster and gives more context but it's difficult and
verbose. I do this in my own setup in order to replace the built-in
completion menu with an alternative one (fzf that opens above the
cursor). You can see it in this demo: https://asciinema.org/a/372068.
The bulk of the code is in
https://github.com/romkatv/zsh4humans/blob/v5/fn/z4h-fzf-complete.

Roman.


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

* Re: completion within a function
  2020-12-30 21:31                 ` Roman Perepelitsa
@ 2020-12-30 22:05                   ` Bart Schaefer
  0 siblings, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-30 22:05 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Felipe Contreras, Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 1:31 PM Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
>
> It's also possible to capture completions without IPC (via zpty or
> otherwise).

Well, sure, if you entirely rewrite compadd and several of the things
that call it.

For interactive shells it's also possible to capture completions
without IPC by using "vared" in the current shell, but that breaks
inside $( ... ) because ZLE is disabled there and can't be re-enabled.
The dance with zpty is just to provide a context where ZLE is still
functional.


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

* Re: completion within a function
  2020-12-30 20:43               ` Bart Schaefer
                                   ` (2 preceding siblings ...)
  2020-12-30 21:31                 ` Roman Perepelitsa
@ 2020-12-30 22:18                 ` Felipe Contreras
  2020-12-30 23:47                   ` Bart Schaefer
  3 siblings, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2020-12-30 22:18 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 2:43 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Dec 30, 2020 at 9:22 AM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > After removing all the unnecessary stuff from the tests, I came up
> > with this script that does list completions:
>
> I think it might be possible to do something even less complicated.
> The basic idea is to first borrow this from the manual:
>
>   zle -C all-matches complete-word _generic
>   bindkey '^Xa' all-matches
>   zstyle ':completion:all-matches::::' completer \
>                  _all_matches _complete
>   zstyle ':completion:all-matches:*' insert true
>
> And then:
>
>   do-complete() { zle -U $'\Cxa\n' }
>   zle -N do-complete
>   run-complete () {
>     vared -i do-complete argv
>   }
>   complete() {
>     local -i n=$argc
>     zpty complete-tty run-complete "$@"
>     zpty -r complete-tty
>     zpty -d complete-tty
>   }
>
> There is likely some additional quoting needed on $@ to assure the
> right arguments are passed to run-complete, and some more could be
> done to separate the context from the results.

I don't know what that's supposed to do, but nothing happens when I
run: complete "g" (other than the fact that "g" is printed).

-- 
Felipe Contreras


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

* Re: completion within a function
  2020-12-30 22:18                 ` Felipe Contreras
@ 2020-12-30 23:47                   ` Bart Schaefer
  2020-12-31  0:08                     ` Bart Schaefer
  2020-12-31  0:12                     ` Felipe Contreras
  0 siblings, 2 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-30 23:47 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 2:19 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> I don't know what that's supposed to do, but nothing happens when I
> run: complete "g" (other than the fact that "g" is printed).

I presumed
  compinit
  zmodload zsh/zpty

"complete g" should display all the commands whose names start with
"g".  Works for me; too much output to show here.

In the zsh source tree, I get for example:

ubuntu% complete ls c
ls config.guess config.h config.h.in config.log config.modules
config.modules.local config.modules.sh config.status config.sub
configure configure.ac

(gmail may line-wrap).  Note the "ls" is still there, removing it is
what I meant by "more could be done to separate the context from the
results."


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

* Re: completion within a function
  2020-12-30 23:47                   ` Bart Schaefer
@ 2020-12-31  0:08                     ` Bart Schaefer
  2020-12-31  0:12                     ` Felipe Contreras
  1 sibling, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-31  0:08 UTC (permalink / raw)
  To: Zsh Users

On Wed, Dec 30, 2020 at 2:19 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> I don't know what that's supposed to do

I just realized that (a) some stuff won't complete as expected because
the context is -vared-, and (b) there's no mention of the -vared-
context anywhere in the manual.


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

* Re: completion within a function
  2020-12-30 23:47                   ` Bart Schaefer
  2020-12-31  0:08                     ` Bart Schaefer
@ 2020-12-31  0:12                     ` Felipe Contreras
  2020-12-31  0:30                       ` Bart Schaefer
  1 sibling, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2020-12-31  0:12 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 5:47 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Dec 30, 2020 at 2:19 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > I don't know what that's supposed to do, but nothing happens when I
> > run: complete "g" (other than the fact that "g" is printed).
>
> I presumed
>   compinit
>   zmodload zsh/zpty

In a login shell or a script?

Using "autoload -U compinit && compinit" does make 'complete g' work
for me in a script, but not 'complete "git --"' for example.

-- 
Felipe Contreras


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

* Re: completion within a function
  2020-12-31  0:12                     ` Felipe Contreras
@ 2020-12-31  0:30                       ` Bart Schaefer
  2020-12-31  0:39                         ` Bart Schaefer
  2020-12-31  1:03                         ` Felipe Contreras
  0 siblings, 2 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-31  0:30 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 4:12 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Wed, Dec 30, 2020 at 5:47 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> >
> > I presumed
> >   compinit
> >   zmodload zsh/zpty
>
> In a login shell or a script?

Either, but I was only trying it in an interactive shell.

> Using "autoload -U compinit && compinit" does make 'complete g' work
> for me in a script, but not 'complete "git --"' for example.

Yeah, see other email about -vared- context changing some things.
That'll take some digging to figure out.


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

* Re: completion within a function
  2020-12-31  0:30                       ` Bart Schaefer
@ 2020-12-31  0:39                         ` Bart Schaefer
  2020-12-31  1:04                           ` Felipe Contreras
  2020-12-31  1:03                         ` Felipe Contreras
  1 sibling, 1 reply; 40+ messages in thread
From: Bart Schaefer @ 2020-12-31  0:39 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

On Wed, Dec 30, 2020 at 4:30 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> Yeah, see other email about -vared- context changing some things.
> That'll take some digging to figure out.

This seems to deal with it:

run-complete () {
  local -A _comps=( ${(kv)_comps} )
  _comps[-vared-]=_normal
  vared -i do-complete argv
}


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

* Re: completion within a function
  2020-12-31  0:30                       ` Bart Schaefer
  2020-12-31  0:39                         ` Bart Schaefer
@ 2020-12-31  1:03                         ` Felipe Contreras
  1 sibling, 0 replies; 40+ messages in thread
From: Felipe Contreras @ 2020-12-31  1:03 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Ray Andrews, Zsh Users

On Wed, Dec 30, 2020 at 6:30 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Dec 30, 2020 at 4:12 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:

> > In a login shell or a script?
>
> Either, but I was only trying it in an interactive shell.

Right. A script needs to load compinit.

-- 
Felipe Contreras


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

* Re: completion within a function
  2020-12-31  0:39                         ` Bart Schaefer
@ 2020-12-31  1:04                           ` Felipe Contreras
  2020-12-31 21:25                             ` Bart Schaefer
  0 siblings, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2020-12-31  1:04 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Wed, Dec 30, 2020 at 6:40 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Dec 30, 2020 at 4:30 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> >
> > Yeah, see other email about -vared- context changing some things.
> > That'll take some digging to figure out.
>
> This seems to deal with it:
>
> run-complete () {
>   local -A _comps=( ${(kv)_comps} )
>   _comps[-vared-]=_normal
>   vared -i do-complete argv
> }

With that I do see the output. There's some garbage in it, but it works.

-- 
Felipe Contreras


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

* Re: completion within a function
  2020-12-31  1:04                           ` Felipe Contreras
@ 2020-12-31 21:25                             ` Bart Schaefer
  2021-01-01  0:12                               ` Ray Andrews
  2021-01-02  0:27                               ` Bart Schaefer
  0 siblings, 2 replies; 40+ messages in thread
From: Bart Schaefer @ 2020-12-31 21:25 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 1081 bytes --]

On Wed, Dec 30, 2020 at 5:04 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> With that I do see the output. There's some garbage in it, but it works.

I'm curious what the garbage is?  Maybe something needs redirection.

Attached (to prevent gmail line wrapping) is a still-fragmentary and
undocumented source-able implementation.

* It works better to discard compstate[vared] than to muck with _comps[-vared-]
* Uses a restricted keymap to avoid messing with the main keymap.
* Some names "protected" with double-underscore as in zed.
* Included a debug function although it's a bit knobbly.

At an interactive command-line, you can type e.g.
  run-complete git --
to see what the completion might be.  I wonder about attaching this to
something ala run-help.

However, that doesn't work if output is redirected anywhere.  If you
want to pipe it or put it in a command substitution, you have to use
e.g.
  complete git -- | less
or
  guesses=( $(complete git --) )

Also, each word has to be individually quoted, you won't get useful results from
  complete "git --"

[-- Attachment #2: complete.txt --]
[-- Type: text/plain, Size: 1315 bytes --]

#autoload

(( $+_comps )) || { autoload -U compinit; compinit -i -D }
zmodload zsh/zpty

if ! bindkey -M __complete 2>/dev/null
then
  bindkey -N __complete
  
  zle -C __complete_all complete-word _generic
  zstyle ':completion:__complete_all::::' completer _all_matches _complete
  zstyle ':completion:__complete_all:*' insert true

  bindkey -M __complete '^Xa' __complete_all
  # bindkey -M __complete '^X?' _complete_debug
  bindkey -M __complete $'\n' .accept-line
  # bindkey -M __complete '^G' .send-break

  __init_complete() { zle -U $'\Cxa\n' }
  zle -N __init_complete
fi

completion-context() {
  if (( debug )); then
    print -u $debug -C 2 -a -r \
    CONTEXT: ":completion:$curcontext" \
    STATE: '' "${(@kv)compstate}"
  fi
}
hide-vared() { compstate[vared]='' }

run-complete () {
  local -a compprefuncs=(hide-vared "${(@)compprefuncs}")
  vared -M __complete -i __init_complete ${${argv:+argv}:-reply}
}

debug-complete() {
  local -i debug
  local -a compprefuncs=(completion-context "${(@)compprefuncs}")
  local -a comppostfuncs=("${(@)comppostfuncs}" completion-context)
  exec {debug}>&2
  complete "$@"
  exec {debug}>&-
}

complete() {
  local -a reply=( "$@" )
  zpty complete-tty run-complete
  { zpty -r complete-tty } always { zpty -d complete-tty }
}

(( ARGC )) && complete "$@"

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

* Re: completion within a function
  2020-12-31 21:25                             ` Bart Schaefer
@ 2021-01-01  0:12                               ` Ray Andrews
  2021-01-02  0:27                               ` Bart Schaefer
  1 sibling, 0 replies; 40+ messages in thread
From: Ray Andrews @ 2021-01-01  0:12 UTC (permalink / raw)
  To: zsh-users

On 2020-12-31 1:25 p.m., Bart Schaefer wrote:
> Also, each word has to be individually quoted, you won't get useful 
> results from
>    complete "git --"
Hafta say I'm pleased you guys are interested in this.



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

* Re: completion within a function
  2020-12-31 21:25                             ` Bart Schaefer
  2021-01-01  0:12                               ` Ray Andrews
@ 2021-01-02  0:27                               ` Bart Schaefer
  2021-01-02 22:24                                 ` Bart Schaefer
  2021-01-03  0:07                                 ` Felipe Contreras
  1 sibling, 2 replies; 40+ messages in thread
From: Bart Schaefer @ 2021-01-02  0:27 UTC (permalink / raw)
  To: Zsh Users

On Thu, Dec 31, 2020 at 1:25 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Wed, Dec 30, 2020 at 5:04 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > With that I do see the output. There's some garbage in it, but it works.
>
> I'm curious what the garbage is?  Maybe something needs redirection.

Ahh ... because it's zpty, the cursor movements get captured along
with everything else.

That's a bit of a monkey wrench unless all you want to do is display
the result.  Hmm.


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

* Re: completion within a function
  2021-01-02  0:27                               ` Bart Schaefer
@ 2021-01-02 22:24                                 ` Bart Schaefer
  2021-01-03  0:28                                   ` Felipe Contreras
  2021-01-03  0:07                                 ` Felipe Contreras
  1 sibling, 1 reply; 40+ messages in thread
From: Bart Schaefer @ 2021-01-02 22:24 UTC (permalink / raw)
  To: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 610 bytes --]

On Fri, Jan 1, 2021 at 4:27 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> Ahh ... because it's zpty, the cursor movements get captured along
> with everything else.

How about this?

ubuntu% complete git --
--bare
--exec-path
--git-dir
--help
--html-path
--info-path
--literal-pathspecs
--man-path
--namespace
--no-pager
--no-replace-objects
--paginate
--version
--work-tree

Earlier, Felipe wrote:
> LISTMAX=1000 # There seems to be a bug in zsh with several thousands

Could this be happening because "zpty -r" will only return up to one
megabyte of output?  If not, what's the symptom of the bug?

[-- Attachment #2: complete.txt --]
[-- Type: text/plain, Size: 2111 bytes --]

#autoload

# Usage: complete commandline
#
# where "commandline" is one or more words, of which the last is the
# prefix of the desired completion.  Thus:
#  complete g
#    completes all commands whose name starts with "g"
#  complete git --
#    completes all options of "git" that begin with two hyphens
#  complete ls c
#    completes all files in $PWD having names starting with "c"
#
# All possible completions are returned, one per line.  There is a
# limit of approximately half a megabyte of total output, as a side-
# effect of vared plus the limit of one megabyte per "zpty -r".

(( $+_comps )) || { autoload -U compinit; compinit -i -D }
zmodload zsh/zpty

if ! bindkey -M __complete 2>/dev/null
then
  bindkey -N __complete
  
  zle -C __complete_all complete-word _generic
  zstyle ':completion:__complete_all::::' completer _all_matches _complete
  zstyle ':completion:__complete_all:*' insert true

  bindkey -M __complete '^Xa' __complete_all
  # bindkey -M __complete '^X?' _complete_debug
  bindkey -M __complete $'\n' .accept-line
  # bindkey -M __complete '^G' .send-break

  __init_complete() { zle -U $'\Cxa\n' }
  zle -N __init_complete
fi

completion-context() {
  if (( debug )); then
    print -u $debug -C 2 -a -r \
    CONTEXT: ":completion:$curcontext" \
    STATE: '' "${(@kv)compstate}"
  fi
}
hide-vared() { compstate[vared]='' }

run-complete () {
  local -a compprefuncs=(hide-vared "${(@)compprefuncs}")
  vared -M __complete -i __init_complete ${${argv:+argv}:-reply}
  (( ARGC )) || print -nrl -- "~~~${(@)reply}~~~"
}

debug-complete() {
  local -i debug
  local -a compprefuncs=(completion-context "${(@)compprefuncs}")
  local -a comppostfuncs=("${(@)comppostfuncs}" completion-context)
  exec {debug}>&2
  complete "$@"
  exec {debug}>&-
}

complete() {
  (( ARGC )) || return 1
  local REPLY reply=( "$@" )
  zpty complete-tty run-complete
  {
    zpty -r complete-tty REPLY $'*~~~*~~~'
  } always {
    zpty -d complete-tty
  }
  reply=( "${(@)${(f)${${REPLY%~~~}#*~~~}}%$'\r'}" )
  shift $((ARGC-1)) reply
  print -lr -- "${(@)reply}"
}

(( ARGC )) && complete "$@"

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

* Re: completion within a function
  2021-01-02  0:27                               ` Bart Schaefer
  2021-01-02 22:24                                 ` Bart Schaefer
@ 2021-01-03  0:07                                 ` Felipe Contreras
  1 sibling, 0 replies; 40+ messages in thread
From: Felipe Contreras @ 2021-01-03  0:07 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Fri, Jan 1, 2021 at 6:27 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Thu, Dec 31, 2020 at 1:25 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> >
> > On Wed, Dec 30, 2020 at 5:04 PM Felipe Contreras
> > <felipe.contreras@gmail.com> wrote:
> > >
> > > With that I do see the output. There's some garbage in it, but it works.
> >
> > I'm curious what the garbage is?  Maybe something needs redirection.
>
> Ahh ... because it's zpty, the cursor movements get captured along
> with everything else.

Yes, that's what happens.

> That's a bit of a monkey wrench unless all you want to do is display
> the result.  Hmm.

In my particular use-case I just need the list of completions in some
format. I use one per line because it's easier on my tests:

  test_completion "git checkout " <<-\EOF
  HEAD Z
  branch-in-other Z
  main Z
  main-in-other Z
  matching-branch Z
  matching-tag Z
  other/branch-in-other Z
  other/main-in-other Z
  EOF

That way I can test the zsh completion system of git-completion the
same way the git project tests the bash completion (I initially wrote
the tests for that too):

https://travis-ci.org/github/felipec/git-completion

-- 
Felipe Contreras


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

* Re: completion within a function
  2021-01-02 22:24                                 ` Bart Schaefer
@ 2021-01-03  0:28                                   ` Felipe Contreras
  2021-01-03  0:53                                     ` Bart Schaefer
  0 siblings, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2021-01-03  0:28 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Sat, Jan 2, 2021 at 4:25 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Fri, Jan 1, 2021 at 4:27 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> >
> > Ahh ... because it's zpty, the cursor movements get captured along
> > with everything else.
>
> How about this?
>
> ubuntu% complete git --
> --bare
> --exec-path
> --git-dir
> --help
> --html-path
> --info-path
> --literal-pathspecs
> --man-path
> --namespace
> --no-pager
> --no-replace-objects
> --paginate
> --version
> --work-tree

I only get 'git --'. It probably depends on your ~/.zshrc

I'm trying it like this:

  ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart 'git --'

The same with my version works fine.

> Earlier, Felipe wrote:
> > LISTMAX=1000 # There seems to be a bug in zsh with several thousands
>
> Could this be happening because "zpty -r" will only return up to one
> megabyte of output?  If not, what's the symptom of the bug?

Probably. The symptom I experienced is that the command never ends,
apparently because the end marker never arrives.

However, I'm trying right now with something as low as 10, and it
still hangs. So I probably added that comment just to highlight that
anything above 1000 is going to fail regardless.

Cheers.

-- 
Felipe Contreras


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

* Re: completion within a function
  2021-01-03  0:28                                   ` Felipe Contreras
@ 2021-01-03  0:53                                     ` Bart Schaefer
  2021-01-03  1:20                                       ` Felipe Contreras
  0 siblings, 1 reply; 40+ messages in thread
From: Bart Schaefer @ 2021-01-03  0:53 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 954 bytes --]

On Sat, Jan 2, 2021 at 4:28 PM Felipe Contreras <felipe.contreras@gmail.com>
wrote:

>
> I'm trying it like this:
>
>   ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart 'git --'
>

Don't pass a single, quoted argument; quote each word separately if needed.

ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart git --

The symptom I experienced is that the command never ends,
> apparently because the end marker never arrives.
>

I ran into this a couple of times myself.  It seems to have something to do
with the definition of "whole string":

     If a PATTERN is given as well, output is read until the whole
     string read matches the PATTERN, even in the non-blocking case.

If there's anything after the end marker, the "whole string" may not
match.  I had to try several different variations to find one that gave
consistent results.

At a guess, you might try:

zle_complete () {
zle list-choices
BUFFER='print -n "<END-CHOICES>"'
zle .accept-line
}

[-- Attachment #2: Type: text/html, Size: 1784 bytes --]

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

* Re: completion within a function
  2021-01-03  0:53                                     ` Bart Schaefer
@ 2021-01-03  1:20                                       ` Felipe Contreras
  2021-01-03  2:21                                         ` Bart Schaefer
  0 siblings, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2021-01-03  1:20 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Sat, Jan 2, 2021 at 6:54 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Sat, Jan 2, 2021 at 4:28 PM Felipe Contreras <felipe.contreras@gmail.com> wrote:
>>
>>
>> I'm trying it like this:
>>
>>   ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart 'git --'
>
> Don't pass a single, quoted argument; quote each word separately if needed.
>
> ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart git --

OK. That works, but it's not particularly useful; there's a difference
between "git checkout<tab>" and "git checkout <tab>".

>> The symptom I experienced is that the command never ends,
>> apparently because the end marker never arrives.
>
> I ran into this a couple of times myself.  It seems to have something to do with the definition of "whole string":
>
>      If a PATTERN is given as well, output is read until the whole
>      string read matches the PATTERN, even in the non-blocking case.
>
> If there's anything after the end marker, the "whole string" may not match.  I had to try several different variations to find one that gave consistent results.
>
> At a guess, you might try:
>
> zle_complete () {
> zle list-choices
> BUFFER='print -n "<END-CHOICES>"'
> zle .accept-line
> }

That doesn't seem to work.

For the record getting the output with bash completion is extremely easy:

  local IFS=$'\n'
  echo "${COMPREPLY[*]}"

-- 
Felipe Contreras


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

* Re: completion within a function
  2021-01-03  1:20                                       ` Felipe Contreras
@ 2021-01-03  2:21                                         ` Bart Schaefer
  2021-01-03  2:47                                           ` Felipe Contreras
  0 siblings, 1 reply; 40+ messages in thread
From: Bart Schaefer @ 2021-01-03  2:21 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

On Sat, Jan 2, 2021 at 5:21 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> On Sat, Jan 2, 2021 at 6:54 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> >
> > ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart git --
>
> OK. That works, but it's not particularly useful; there's a difference
> between "git checkout<tab>" and "git checkout <tab>".

The latter is just

ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart git checkout ''


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

* Re: completion within a function
  2021-01-03  2:21                                         ` Bart Schaefer
@ 2021-01-03  2:47                                           ` Felipe Contreras
  2021-01-03  3:30                                             ` Bart Schaefer
  2021-01-03 17:50                                             ` Bart Schaefer
  0 siblings, 2 replies; 40+ messages in thread
From: Felipe Contreras @ 2021-01-03  2:47 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Sat, Jan 2, 2021 at 8:21 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Sat, Jan 2, 2021 at 5:21 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > On Sat, Jan 2, 2021 at 6:54 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> > >
> > > ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart git --
> >
> > OK. That works, but it's not particularly useful; there's a difference
> > between "git checkout<tab>" and "git checkout <tab>".
>
> The latter is just
>
> ZDOTDIR=/tmp/empty-home zsh /tmp/complete-bart git checkout ''

OK. That works. Takes 8.7s to complete on the Linux repository with
3350 entries on my system, but it does complete.

You do see why I think 'git checkout ' is more friendly than 'git'
'checkout' '', right?

I'll inspect what the script is doing later on. Thanks.

Do you feel confident enough to use this approach on your own tests
though? Instead of the current convoluted one.

Cheers.

-- 
Felipe Contreras


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

* Re: completion within a function
  2021-01-03  2:47                                           ` Felipe Contreras
@ 2021-01-03  3:30                                             ` Bart Schaefer
  2021-01-03 23:16                                               ` Felipe Contreras
  2021-01-03 17:50                                             ` Bart Schaefer
  1 sibling, 1 reply; 40+ messages in thread
From: Bart Schaefer @ 2021-01-03  3:30 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

On Sat, Jan 2, 2021 at 6:47 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> OK. That works. Takes 8.7s to complete on the Linux repository with
> 3350 entries on my system, but it does complete.

That's likely because it's doing "compinit -D".  It would go faster
for subsequent tests if they all ran in the same shell with that
pre-loaded.

> You do see why I think 'git checkout ' is more friendly than 'git'
> 'checkout' '', right?

For your usage, I do, but that makes it a bit harder to separate the
context from the completions.

> Do you feel confident enough to use this approach on your own tests
> though?

You mean for Test/Y*.ztst ?  No, it's not intended for that.  The
tests in the zsh suite examine cursor placement and the layout of
listings; this intentionally only generates the possible matches.


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

* Re: completion within a function
  2021-01-03  2:47                                           ` Felipe Contreras
  2021-01-03  3:30                                             ` Bart Schaefer
@ 2021-01-03 17:50                                             ` Bart Schaefer
  1 sibling, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2021-01-03 17:50 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 247 bytes --]

On Sat, Jan 2, 2021 at 6:47 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> You do see why I think 'git checkout ' is more friendly than 'git'
> 'checkout' '', right?

Try this one.  I think I'm probably done fooling around with this.

[-- Attachment #2: complete.txt --]
[-- Type: text/plain, Size: 2883 bytes --]

#autoload

# Usage: complete commandline
#
# where "commandline" is one or more words, of which the last is the
# prefix of the desired completion.  If the commandline is a single
# argument, it is split into words using expansion flag (z) with any
# trailing whitespace treated as delimiting a final empty word.
#
# Thus:
#  complete g
#    completes all commands whose name starts with "g"
#  complete git --
#    completes all options of "git" that begin with two hyphens
#  complete 'git checkout -- '
#    completes all modified files in the current repository
#
# All possible completions are returned, one per line.  There is a
# limit of approximately half a megabyte of total output, as a side-
# effect of vared plus the limit of one megabyte per "zpty -r".
#
# If the variable CURSOR is defined, that position within commandline
# is used as the start of the completion.  This is only useful when
# the COMPLETE_IN_WORD option is enabled.  Note, if CURSOR does not
# fall either immediately before, within, or after the last word,
# the results are unpredictable.
#
# Other limitations:
#  Only completion is performed, not expansion.
#  Splitting the input with (z) collapses any consecutive whitespace,
#  which may affect the use of CURSOR.

(( $+_comps )) || { autoload -U compinit; compinit -i -D }
zmodload zsh/zpty

if ! bindkey -M __complete 2>/dev/null
then
  bindkey -N __complete
  
  zle -C __complete_all complete-word _generic
  zstyle ':completion:__complete_all::::' completer _all_matches _complete
  zstyle ':completion:__complete_all:*' insert true

  bindkey -M __complete '^Xa' __complete_all
  # bindkey -M __complete '^X?' _complete_debug
  bindkey -M __complete $'\n' .accept-line
  # bindkey -M __complete '^G' .send-break

  __init_complete() {
    CURSOR=${__cursor:-$CURSOR}
    zle -U $'\Cxa\n'
  }
  zle -N __init_complete
fi

completion-context() {
  if (( debug )); then
    print -u $debug -C 2 -a -r \
    CONTEXT: ":completion:$curcontext" \
    STATE: '' "${(@kv)compstate}"
  fi
}
hide-vared() { compstate[vared]='' }

run-complete () {
  local -a compprefuncs=(hide-vared "${(@)compprefuncs}")
  vared -M __complete -i __init_complete ${${argv:+argv}:-reply}
  (( ARGC )) || print -nrl -- "~~~${(@)reply}~~~"
}

debug-complete() {
  local -i debug
  local -a compprefuncs=(completion-context "${(@)compprefuncs}")
  local -a comppostfuncs=("${(@)comppostfuncs}" completion-context)
  exec {debug}>&2
  complete "$@"
  exec {debug}>&-
}

complete() {
  (( ARGC )) || return 1
  (( ARGC == 1 )) && argv=( "${(@)${(z):-${1}x}%x}" )
  local REPLY reply=( "$@" ) __cursor=$CURSOR
  zpty complete-tty run-complete &&
  {
    zpty -r complete-tty REPLY $'*~~~*~~~'
  } always {
    zpty -d complete-tty
  }
  reply=( "${(@)${(f)${${REPLY%~~~}#*~~~}}%$'\r'}" )
  shift ARGC-1 reply
  print -lr -- "${(@)reply}"
}

(( ARGC )) && complete "$@"

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

* Re: completion within a function
  2021-01-03  3:30                                             ` Bart Schaefer
@ 2021-01-03 23:16                                               ` Felipe Contreras
  2021-01-05 19:57                                                 ` Bart Schaefer
  0 siblings, 1 reply; 40+ messages in thread
From: Felipe Contreras @ 2021-01-03 23:16 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On Sat, Jan 2, 2021 at 9:31 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> On Sat, Jan 2, 2021 at 6:47 PM Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
> >
> > OK. That works. Takes 8.7s to complete on the Linux repository with
> > 3350 entries on my system, but it does complete.
>
> That's likely because it's doing "compinit -D".  It would go faster
> for subsequent tests if they all ran in the same shell with that
> pre-loaded.

At the moment I can't do that, it has to be a new shell every time,
and your version seems to take longer to load, slowing the tests.

> > You do see why I think 'git checkout ' is more friendly than 'git'
> > 'checkout' '', right?
>
> For your usage, I do, but that makes it a bit harder to separate the
> context from the completions.

OK. But it still doesn't work correctly: I can't pass empty arguments
in the middle of a command-line.

For example in the tests I added a fake "func" command that calls a
function, for example:

  git func __gitcomp_opts "octopus ours recursive resolve subtree" ""
"re" --strategy=re

Why my method that works fine, with your method what effectively ends
up happening is the equivalent of:

  git func __gitcomp_opts "octopus ours recursive resolve subtree"
"re" --strategy=re

The "" is there in the array, I don't know why varead seems to ignore it.

Also, I don't understand why is there an argv there:

  vared -M __complete -i __init_complete ${${argv:+argv}:-reply}
  (( ARGC )) || print -nrl -- "~~~${(@)reply}~~~"

Isn't "reply" always used? And ARGC is always 0?

Cheers.

-- 
Felipe Contreras


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

* Re: completion within a function
  2021-01-03 23:16                                               ` Felipe Contreras
@ 2021-01-05 19:57                                                 ` Bart Schaefer
  0 siblings, 0 replies; 40+ messages in thread
From: Bart Schaefer @ 2021-01-05 19:57 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Zsh Users

On Sun, Jan 3, 2021 at 3:16 PM Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>
> [...] your version seems to take longer to load, slowing the tests.

I don't know what your version is loading or whether a .zcompdump file
might be getting used to speed that part up.  When I try it (with the
zsh-dist-provided git completions) it spends more of its time
populating git data than anything else.

> [...] it still doesn't work correctly: I can't pass empty arguments
> in the middle of a command-line.

What does an empty argument in the middle of the line mean to the
completion result?  Which word are you trying to complete?

I thought you were passing a single string as the only argument to my
"complete" function?  If that's true, how is the empty argument
represented in that string?

> Also, I don't understand why is there an argv there:
>
>   vared -M __complete -i __init_complete ${${argv:+argv}:-reply}
>   (( ARGC )) || print -nrl -- "~~~${(@)reply}~~~"
>
> Isn't "reply" always used? And ARGC is always 0?

The ARGC/argv stuff is there so that you can call run-complete directly:

  % run-complete "git checkout -- "

which only works from an interactive command line, and just prints the
completion without forking off a zpty.

Called as the zpty command from complete, yes, ARGC is always zero and
reply is used.


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

end of thread, other threads:[~2021-01-05 19:58 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-29 15:24 completion within a function Ray Andrews
2020-12-29 18:52 ` Bart Schaefer
2020-12-29 19:36   ` Felipe Contreras
2020-12-29 19:41     ` Roman Perepelitsa
2020-12-29 21:04   ` Ray Andrews
2020-12-29 21:21     ` Ray Andrews
2020-12-29 22:03       ` Bart Schaefer
2020-12-29 21:48     ` Bart Schaefer
2020-12-30  0:31       ` Ray Andrews
2020-12-30  4:34         ` Roman Perepelitsa
2020-12-30 16:45           ` Ray Andrews
2020-12-30 17:21             ` Felipe Contreras
2020-12-30 20:43               ` Bart Schaefer
2020-12-30 20:46                 ` Bart Schaefer
2020-12-30 20:50                 ` Ray Andrews
2020-12-30 21:31                 ` Roman Perepelitsa
2020-12-30 22:05                   ` Bart Schaefer
2020-12-30 22:18                 ` Felipe Contreras
2020-12-30 23:47                   ` Bart Schaefer
2020-12-31  0:08                     ` Bart Schaefer
2020-12-31  0:12                     ` Felipe Contreras
2020-12-31  0:30                       ` Bart Schaefer
2020-12-31  0:39                         ` Bart Schaefer
2020-12-31  1:04                           ` Felipe Contreras
2020-12-31 21:25                             ` Bart Schaefer
2021-01-01  0:12                               ` Ray Andrews
2021-01-02  0:27                               ` Bart Schaefer
2021-01-02 22:24                                 ` Bart Schaefer
2021-01-03  0:28                                   ` Felipe Contreras
2021-01-03  0:53                                     ` Bart Schaefer
2021-01-03  1:20                                       ` Felipe Contreras
2021-01-03  2:21                                         ` Bart Schaefer
2021-01-03  2:47                                           ` Felipe Contreras
2021-01-03  3:30                                             ` Bart Schaefer
2021-01-03 23:16                                               ` Felipe Contreras
2021-01-05 19:57                                                 ` Bart Schaefer
2021-01-03 17:50                                             ` Bart Schaefer
2021-01-03  0:07                                 ` Felipe Contreras
2020-12-31  1:03                         ` Felipe Contreras
2020-12-30  6:45         ` Bart Schaefer

zsh-users

This inbox may be cloned and mirrored by anyone:

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

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 zsh-users zsh-users/ http://inbox.vuxu.org/zsh-users \
		zsh-users@zsh.org
	public-inbox-index zsh-users

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.users


code repositories for the project(s) associated with this inbox:

	https://git.vuxu.org/mirror/zsh/

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