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

Re: [BUG] complist interactive mode overwrites command line




On 04/08/2021 18:30, Marlon Richert wrote:
% zmodload zsh/complist
% bindkey '^I' menu-select
% MENUMODE=interactive
% touch test{1,2}
% : ; foobar
    ^ 1. Type the above line in its entirety.
      2. Place the cursor before the ;
      3. Press Tab.
      4. Press Enter.
% : test1 bar
    ^ Completion is written over existing buffer contents.


Hello,

I think I have an acceptable solution to this issue, although I’m quite unaware of all the intricacies of the Zsh source code,
and had 0 knowledge of Zsh internals until 2 days ago...
All I can say is that it doesn’t cause the tests to fail,
And that after a day of usage it doesn’t seem to break anything else (in my limited use-cases).

Basically, when entering an interactive select completion menu, the first completion in the list gets “selected” (it’s highlighted) but not inserted in the command line.
In the above test case, that would be “test1”.
At that time, compresult.c:do_single was called with “test1” completion, then complist.c:domenuselect restored the command line to its original content.
That means the minfo struct was updated by do_single. In that case, we would get minfo { .len = 5, .end = 7 }.

When leaving the interactive mode (pressing Enter to accept the first completion, or selecting another completion like using arrow keys),
minfo.len
characters are removed to “insert the next” completion (5 characters, but in fact our command line is still “: ; foobar”, so only 1 character should be erased).

So I just tried fixing it by correcting the values in minfo when domenuselect restores the command line content,
Which seems to me, is what should happen as far as I understand :

diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 9cb89a60d..f2eb3837d 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -2443,6 +2443,8 @@ domenuselect(Hookdef dummy, Chdata dat)
             strncpy(zlemetaline, origline, l);
             zlemetacs = origcs;
             setmstatus(status, NULL, 0 , 0, NULL, NULL, NULL);
+           minfo.len = origlpre;
+           minfo.end = minfo.pos + minfo.len;
         } else if (strpfx("search", s)) {
             mode = (strstr(s, "back") ? MM_BSEARCH : MM_FSEARCH);
         }



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