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

accept-and-hold in interactive mode of menu select

In the interactive mode of menu select, accept-and-hold
does not work as I expect. In the worst case, it results in
an infinite loop.

### create a file with the following contents:

$ cat init
zmodload zsh/complist
autoload -Uz compinit
zstyle ':completion:*' menu on select=2
bindkey '^K' vi-insert
bindkey '^L' accept-and-hold

### create a test directory and a few files:

$ mkdir test
$ touch test/{aaaa,abbb,abbc}

### Start a new shell, and setup menu select:

$ zsh -f
% source init

### Test-1:

% ls test/
>>> hit TAB
% ls test/aaaa
aaaa  abbb  abbc  abbd

>>> hit ^K to go into the interactive mode:

% ls test/
interactive: test/[]
aaaa*  abbb  abbc
 ('*' indicates where the selection in the list)

>>> type ab

% ls test/ab
interactive: test/abb[]
abbb*  abbc

>>> hit ^L

% ls test/ab test/abbc
abbb  abbc*

Note that the 1st word on the command line is not updated to test/abbb.

### Test-2:

% ls test/{

>>> hit TAB

% ls test/{aaaa
aaaa* abbb abbc

>>> hit ^K

% ls test/{
interactive: test/[]
aaaa  abbb  abbc

>>> type ab

% ls test/{ab
interactive: test/{abb[]
abbb* abbc

>>> hit ^L

then zsh goes into an infinite loop; ^C does not work.

gdb indicates that it is looping in a "do {...} while(...)" loop at
lines 1222-1240 of compresult.c, in function do_menucmp(). It seems
the 1st condition in while() is always true; menuacc==1 and hasbrpsfx()
always returns 0.

It seems the real problem is that, as the Test-1 indicates, accept-and-
hold does not update the command line. I tried the patch below, and it
does avoid the infinite loop. But it is far from sufficient; for example,
the ^L above now gives (as I expect)

% ls test/{abbb,abbc

but if I hit ^K to go to the interactive mode again, then I get

% ls test/{ab

diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index c129940..80f8dd5 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -2790,6 +2790,8 @@ domenuselect(Hookdef dummy, Chdata dat)
 	    Menustack s = (Menustack) zhalloc(sizeof(*s));
 	    int ol;
+	    if (mode == MM_INTER)
+		do_single(*minfo.cur);
             mode = 0;
 	    s->prev = u;
 	    u = s;

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