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

Re: [BUG] compinit interactive mode overwrites command line



On Monday, May 12th, 2025 at 09:40, Mikael Magnusson <mikachu@xxxxxxxxx> wrote:

> On Wed, May 7, 2025 at 10:02 PM Andrea Manenti andrea.manenti@xxxxxxxxx wrote:
> 
> > This bug was opened long ago but received no activity. I am reopening a new one hoping to give it more visibility.
> > 
> > ## Steps for reproducing
> > 
> > `% autoload -Uz compinit % compinit % zstyle ':completion:*' menu yes select interactive % ls Do rest-of-command interactive: Do[] Documents/ Downloads/`
> > 
> > Clicking a down arrow or a tab results in
> > 
> > `% ls Downloads/-command Documents/ Downloads/`
> > 
> > ## Issue
> > 
> > If a completion is triggered in the middle of a command, what comes next is overwritten. It should be shifted to the right instead.
> > 
> > Important point for reproducing: this only happens if there are more than one option.
> > 
> > ## Relevant links:
> > 
> > StackOverflow original question: https://stackoverflow.com/questions/68643931/zsh-s-tab-completion-overwrites-whats-next
> > zsh Mailing List previous submission: https://www.zsh.org/mla/workers/2021/msg01466.html
> 
> 
> This change appears to fix it, but I just looked for MM_INTER in
> complist.c and tried poking at it until something changed, so it's
> very possible this breaks something else. The comment, but not the
> piece of code itself, was added by pws in workers/20482.
> 
> I think most people would not use this configuration though, it would
> be more common to have just 'yes select' as the menu style, and if you
> want to search the matches, you'd press ctrl-r after entering menu
> selection. At least that's what I do, and it works fine already.
> 
> diff --git i/Src/Zle/complist.c w/Src/Zle/complist.c
> index 8a3fd791f2..7fa184195c 100644
> --- i/Src/Zle/complist.c
> +++ w/Src/Zle/complist.c
> @@ -2434,28 +2434,22 @@ domenuselect(Hookdef dummy, Chdata dat)
> else if (step < 0)
> if ((step += zterm_lines - nlnct) < 0)
> step = 1;
> }
> if ((s = getsparam("MENUMODE"))) {
> if (!strcmp(s, "interactive")) {
> - int l = strlen(origline);
> 
> /*
> * In interactive completion mode we don't insert
> * the completion onto the command line, instead
> * we show just what the user has typed and
> * the match so far underneath (stored in "status").
> * So put the command line back to how it
> * was before completion started.
> */
> mode = MM_INTER;
> - zlemetacs = 0;
> - foredel(zlemetall, CUT_RAW);
> - spaceinline(l);
> - strncpy(zlemetaline, origline, l);
> - zlemetacs = origcs;
> setmstatus(status, NULL, 0 , 0, NULL, NULL, NULL);
> } else if (strpfx("search", s)) {
> mode = (strstr(s, "back") ? MM_BSEARCH : MM_FSEARCH);
> }
> }
> if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus)
> 
> 
> --
> Mikael Magnusson

I tried your patch, thanks!

I think this fixes the problem if I look for the options using the arrows, but the problem remains
if I keep writing the command to make it more specific. Steps:

 1. Go to a folder with "Documents", "Downloads", "Desktop".
 2. Write "cd D rest"
 3. Go with the cursor after "D"
 4. Press [TAB] (Desktop autocompletes)
 5. Press "o" (Desktop option disappears, command line is "cd Do rest")
 6. Press [Enter]
 7. "rest" is overwritten.

Let me give context for why I find this flow useful:

Suppose the command "Foo" can complete to "FooBarLong1", "FooBarLong2", ..., "FooBarLong10",
"FooSomethingElse". If I want "FooSomethingElse" I would either have to press the right arrow 10
times or erase FooBarLong1 until Foo pressing backspace 8 times. Whereas if it appears without
completing I could just type "FooS" until all the FooBarLongss disappear, then press [Enter].

Andrea






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