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

Re: [BUG] _gnu_generic completer produces broken output

> 2021/07/23 4:39l Marlon Richert <marlon.richert@xxxxxxxxx> wrote:
> Looks like the same bug as workers 48091.

It seems the problem occurs if the completion function (_gnu_generic
in this case or _typeset in workers/48091) is called more than once
during the completion. This causes _describe to be called more than once.
As noted in the comment at the top of _describe, this may generate
garbled output, but I don't know how to fix this.

In the case of _gnu_generic:

> % autoload compinit && compinit
> % compdef _gnu_generic -command- -P '*'
> % pip3 -

_complete_debug shows:

  +_normal:39> _dispatch -s pip3 pip3 /usr/local/bin/pip3 -default-

_dispatch calls _gnu_generic at line 73

   +_dispatch:73> eval _gnu_generic

for three times with service = pip3, /usr/local/bin/pip3 and -default-.

A workaround is

_gnu_generic_once () { _gnu_generic; _compskip=all }
compdef _gnu_generic_once -P '*'

The case in workers/48091 is more obscure for me:

> autoload -Uz compinit; compinit
> zstyle ':completion:*:functions' ignored-patterns '[[:punct:]]*[[:alnum:]]*'
> zstyle ':completion:*:options' matcher 'b:-=+'

First _main_complete:218 calls _complete, but it fails (returns 1); why?
Anyway _typeset is called once here.
Since _complete fails, _main_complete calls _ignored. If the ignored-patterns
style is set as above, 

 +_ignored:5> [[ _matcher_num -gt 1 || 958 -eq 0 ]]

there are many (958) ignored words and _ignored thinks it must re-generate the
words and calls _typset again.

The patch below for _typeset may be a possible workaround.

diff --git a/Completion/Zsh/Command/_typeset b/Completion/Zsh/Command/_typeset
index aecacb112..0976d9347 100644
--- a/Completion/Zsh/Command/_typeset
+++ b/Completion/Zsh/Command/_typeset
@@ -128,7 +128,7 @@ if [[ "$state" = vars_eq ]]; then
       _wanted functions expl 'shell function' compadd -a args
-    else
+    elif [[ $PREFIX != [-+]* ]]; then
   elif [[ "$PREFIX" = *\=* ]]; then

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