prezto icon indicating copy to clipboard operation
prezto copied to clipboard

Tab completion eats a line

Open hotpxl opened this issue 8 years ago • 44 comments

I use zsh 5.3.1 with prezto current master. I traced a problem to this line. To reproduce the problem, have editor plugin enabled and choose a multiline prompt theme. Trigger tab completion. Normally it would show "..." to indicate it's completing, then it hits this line zle redisplay and it will eat a line upwards. Hit tab repeatedly and it will eat lines repeatedly (make sure tab triggers a "..." but not a selection among choices).

Commenting out this line solves this issue.

hotpxl avatar Dec 27 '16 10:12 hotpxl

The problem reproduces when zle expand-or-complete generates a no matches found warning, but the cursor is one line above it, and somehow zle redisplay erases one line too many on the top

hotpxl avatar Dec 27 '16 10:12 hotpxl

I traced it to a few lines in the upstream zsh changelog. Guess it has nothing to do with prezto.

hotpxl avatar Dec 27 '16 12:12 hotpxl

@hotpxl I suffer from the exact same issue. Do you know if commenting out this line has any side-effect?

I also noticed that the only multiline prompt theme where it doesn't happen is pure. Maybe they do something differently.

mdemierre avatar Dec 27 '16 14:12 mdemierre

I just found the side effect of commenting out the line. During completion (I entered "cd ." then pressed Tab) it does this: term_completion

Pressing Enter still goes to the dir correctly, it's just a display problem. Better than completion eating lines though.

Also, when using Backspace to erase that line, the bold dot stays and the command name is not erased.

mdemierre avatar Dec 27 '16 14:12 mdemierre

I think I have found the issue.

Refering to this patch from zsh.

commit 564fb25e821bdd143d23c4e22bc98254b0f8dd59
Author: Barton E. Schaefer <[email protected]>
Date:   Thu Mar 3 13:03:40 2016 -0800

    38048: fix "zle redisplay" when called while a listing is below the prompt

diff --git a/ChangeLog b/ChangeLog
index 6b80b19f5..691f54c77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2016-03-03  Barton E. Schaefer  <[email protected]>

+       * 38048: Src/zle_refresh.c: fix "zle redisplay" when called while
+       a listing is below the prompt (e.g., from interrupt handler)
+
        * 38039: Src/options.c: POSIXy behavior for "set +o"

 2016-02-26  Peter Stephenson  <[email protected]>
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 7e4f32876..aca676a1c 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -2435,8 +2435,8 @@ redisplay(UNUSED(char **args))
     moveto(0, 0);
     zputc(&zr_cr);             /* extra care */
     tc_upcurs(lprompth - 1);
-    resetneeded = 1;
-    clearflag = 0;
+    resetneeded = !showinglist;
+    clearflag = showinglist;
     return 0;
 }

So why does this affect the completion prompt? It's the way module editor handles completion. In vanilla zsh, tab is bound to expand-or-complete. But in prezto, tab is bound to call expand-or-complete first and then redisplay. It's calling redisplay because otherwise the ... indicator won't disappear (like in @mdemierre case). I guess redisplay cannot fully handle the case where there is already a line under current cursor. So it eats up a line from above instead. All in all, probably it's better to just call expand-or-complete and erase the indicator by some other means.

hotpxl avatar Dec 27 '16 18:12 hotpxl

@mdemierre I think the reason why pure works is that its prompt is drawn by a zsh function instead of $PROMPT. It is printed to the screen so zle knows how many lines there are.

hotpxl avatar Dec 27 '16 18:12 hotpxl

Thought I was going crazy with this. Thanks for opening the bug and tracing it back to upstream.

abraithwaite avatar Dec 27 '16 22:12 abraithwaite

My guess is that zle somehow hard-coded PROMPT to have only one line. So this bug occurs when you embed a newline in PROMPT. My workaround now is to print the prompt in precmd hook.

hotpxl avatar Dec 28 '16 03:12 hotpxl

I could also fix this by printing the first line of the prompt in precmd, and only use PROMPT for the second line. It seems that PROMPT was in fact never intended to support multiple lines in zsh.

I guess the editor module should be patched, since it affects multiline prompt themes from zsh too.

mdemierre avatar Dec 29 '16 11:12 mdemierre

I'd be surprised if the ZSH committers didn't fix this upstream. There are tons of multi-line prompts out there. It worked fine before (even if it was a fluke), so why willingly remove that functionality?

Unless I'm missing an announcement somewhere that says the prompt should be printed in precmd.

abraithwaite avatar Dec 29 '16 18:12 abraithwaite

I'm experiencing the same issue. I'm glad someone has gotten to the bottom of this.

hurricanehrndz avatar Jan 09 '17 17:01 hurricanehrndz

Can also confirm that printing the first line and making prompt a single line seems to fix the issue.

hurricanehrndz avatar Jan 09 '17 22:01 hurricanehrndz

Could someone fix this for the steeef theme?

shizonic avatar Jan 10 '17 13:01 shizonic

jfi: Experiencing this with oh-my-zsh as soon as i set COMPLETION_WAITING_DOTS to true (this triggers 'zle redisplay' being called). See: https://github.com/robbyrussell/oh-my-zsh/issues/5767

muesli avatar Jan 10 '17 14:01 muesli

I noticed this as well starting with 5.3. It's being discussed here: http://www.zsh.org/mla/workers//2017/msg00021.html.

In the meantime I'm sticking with 5.2.

ryankask avatar Jan 10 '17 15:01 ryankask

I am also having issues here only with certain themes (such as ys).

ZSH: 5.1.1

niij avatar Jan 16 '17 20:01 niij

After getting frustrated trying find a way to downgrade zsh to 5.2 using brew, this was the "solution" that I used. Don't close the session or open new ones until this finishes.

export HOMEBREW_NO_AUTO_UPDATE=1 && \
cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula && \
git checkout 5ba8893805b95b07688df90a8d0911e91709855f && \
brew remove zsh --force && \
brew install zsh && \
git checkout master && \
brew upgrade && \
brew switch zsh 5.2

Why switching back and forth? to force brew installing an older version and not switching/removing it after executing brew upgrade/cleanup.

I'd like to learn if there's an easier/cleaner way to do this.

cesalazar avatar Jan 22 '17 19:01 cesalazar

I think I did something like:

brew uninstall zsh
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/e9d14f68b895eeb276806a956378293abe5e4bd8/Formula/zsh.rb
brew pin zsh

ryankask avatar Jan 22 '17 23:01 ryankask

I'm not currently using prezto, but I use a version of the steeef theme and an old version of its editor script (modules/editor/init.zsh). I had this very same issue, and tracked it down to a line that reads:

  bindkey -M "$keymap" "$key_info[Control]I" \
    expand-or-complete-with-indicator

Without this re-binding, tab completion doesn't eat a line for me. I think you should try if commenting out this line fixes the issue for you.

cosarara avatar Jan 30 '17 00:01 cosarara

Thanks for the hint. This helps with eating a line (basically due to removal of the zle redisplay inside expand-or-complete-with-indicator), but it breaks other stuff, for example showing ... while waiting for the tab complete.

So, as of today the only reliable way is to stay on zsh 5.2

maximbaz avatar Jan 30 '17 01:01 maximbaz

Following up on this issue. The latest ZSH master branch fixed this issue. I believe it is commit 34656ec2f00d6669cef56afdbffdd90639d7b465 that fixed this issue but I have not verified this. So wait for the next ZSH release 5.3.2 and everything will be fine!

Thanks for the discussion ppl!

hotpxl avatar Feb 27 '17 01:02 hotpxl

Thanks for the follow up @hotpxl !

facastagnini avatar Mar 04 '17 16:03 facastagnini

For people using zsh installed via homebrew, I confirm that the latest version resolves the issue.

You can install --head by running the following:

$ brew unlink zsh
$ brew install zsh --HEAD
screenshot 2017-05-08 12 16 12

ladislas avatar May 08 '17 10:05 ladislas

Applying just the patch in question worked for me in Arch linux.

https://github.com/zsh-users/zsh/commit/34656ec2f00d6669cef56afdbffdd90639d7b465.patch

abraithwaite avatar May 24 '17 06:05 abraithwaite

I'm still having this issue with zsh 5.4.2 + prezto + fzf.

fabioperez avatar Mar 20 '18 19:03 fabioperez

Which prezto commit are you on?

belak avatar Mar 20 '18 20:03 belak

@belak master HEAD (b3c27bb16460c677eabbe3d8e210f79fb5e8189b).

fabioperez avatar Mar 20 '18 20:03 fabioperez

And which prompt?

belak avatar Mar 20 '18 20:03 belak

Any multi-line prompt that I try (bigfade, adam2, elite2 etc.).

fzf is also up-to-date.

fabioperez avatar Mar 20 '18 20:03 fabioperez

Looks like we're tracking this in #1488. I'll try to investigate a bit more in depth later.

belak avatar Mar 20 '18 20:03 belak

@fabioperez Have you tried using my theme?

hurricanehrndz avatar Mar 20 '18 20:03 hurricanehrndz

@hurricanehrndz What theme? Can you provide a link?

fabioperez avatar Mar 21 '18 16:03 fabioperez

Still having this issue with zsh 5.4.2 and pretzo.. This is exactly what happens: https://asciinema.org/a/ivLUGJP9Quk3GVYrWSJZm3vOA

p3rsephone avatar Mar 21 '18 22:03 p3rsephone

I have a temporary fix. You could try but I doubt it would work. Add the following after the initialization code to override the expand function.

function revert-expand-or-complete {
  zle expand-or-complete
}

zle -N expand-or-complete-with-indicator revert-expand-or-complete

hotpxl avatar Mar 23 '18 05:03 hotpxl

@hotpxl Thanks! That worked perfectly 😄

p3rsephone avatar Mar 27 '18 00:03 p3rsephone

@hotpxl this worked for me! thanks! Edit: Actually, now tab completion on mv is broken, giving me

(eval):1: _mv: function definition file not found
(eval):1: _mv: function definition file not found
(eval):1: _mv: function definition file not found
(eval):1: _mv: function definition file not found

seeholza avatar Apr 02 '18 09:04 seeholza

@flinz, I had this issue with the mv command as well. (My zsh version: zsh 5.5.1 (x86_64-apple-darwin16.7.0), which as of this writing is the zsh that is installed by default with Homebrew.)

Running which -a _mv produced the following for me:

_mv () {
        # undefined
        builtin autoload -XUz
}

Which seems strange given that mv should be supplied by zsh itself; the fact I get undefined here would imply that zsh's mv completion isn't getting loaded correctly on install (which others in this thread have already pointed out is the issue).

I ran across a similar thread from years ago for broken shell autocomplete in an issue opened on Oh My Zsh. One of the comments recommended running the following to fix the issue:

rm -f ~/.zcompdump*
exec zsh -l

AFAICT (and someone can correct me if I'm wrong), the first command there removes the zsh completion cache files; exec zsh -l will run zsh in place of the current shell (-l is used to tell the program that this is a login session)—it just seems to be a way to restart zsh.

Running which -a _mv now shows the correct function contents, and mv autocomplete works as expected once again.


UPDATE:

So the above only solves the issue and makes zsh's mv autocompletion work as expected for the current shell. If a new terminal window is opened, mv is "broken" once again. I don't even know how to patch this locally (since having e.g. exec zsh -l in one's .zshrc would create an infinite loop of running the zsh command over and over).

This is a bummer. I don't know enough about how zsh completion works to know the proper solution for this (what a perfect tell on how much we rely on things that we don't fully understand, ha!), so I guess I'm stuck running the exec zsh -l command manually in each window until I (or, rather likely, someone else) figures out the root of the issue.


UPDATE:

Today, when I opened a new terminal window, mv is working fine without me having to run exec zsh -l. This doesn't make a whole tone of sense to me given that yesterday this exact same action resulted in a still broken mv autocomplete (unless exec zsh -l was run). Now I am unable to reproduce the issue, which I suppose is a good thing (i.e. I'm happy mv works as expected now), but is rather unsatisfying given that I'm not entirely sure what fixed the issue.

If anyone else happens to read this comment and tries the steps outlined in the initial part of this comment, please let me know what your outcome is. Given that my mv autocomplete works now, I assume that removing the completion cache files and restarting zsh is a viable solution, but the fact that it didn't solve the problem "immediately" for me gives me pause.

indiesquidge avatar Jun 05 '18 18:06 indiesquidge

@indiesquidge Thx a lot for resolve the mv autocomplete problem. I run rm -f ~/.zcompdump* and restart iTerm, everything is ok. But if rm -f ~/.zcompdump* then exec zsh -l and restart terminal, mv is still broken. So weird.

jerryshang avatar Jul 18 '18 06:07 jerryshang

@indiesquidge @jerryshang I too faced this problem. rm -rf ~/.zcompdump* and restart iTerm worked where as rm -f ~/.zcompdump* then exec zsh -l and restart terminal, mv is still broken ..

pushparajxa avatar Oct 07 '18 17:10 pushparajxa

Weird, I also got this recently. Using the rm -f ~/.zcompdump* then restarting iTerm2 fixed it as well. Thanks!

kkirsche avatar Jan 24 '19 03:01 kkirsche

I was able to work around it by commenting out the completing feature. I do not mind, this completing feature. For example, if you are using paradox theme, change it as follows. ~/.zprezto/modules/prompt/functions/prompt_paradox_setup

# zstyle ':prezto:module:editor:info:completing' format '%B%F{red}...%f%b'

yoshixmk avatar Jul 19 '19 14:07 yoshixmk

I'm also having this issue.

 ❯❯❯ zsh --version
zsh 5.7.1 (x86_64-apple-darwin18.2.0)

I installed zsh with brew. I also tried installing the zsh head (https://github.com/sorin-ionescu/prezto/issues/1245#issuecomment-299828536) but that didn't help. I'm using a custom multi-line prompt based on the default. I'm on 7c94154. @hotpxl suggestion from https://github.com/sorin-ionescu/prezto/issues/1245#issuecomment-375550386 worked for me by adding that code to my .zshrc

paymog avatar Jan 06 '20 22:01 paymog

for people having this issue on oh-my-zsh: you can refer to this issue which has a solution: https://github.com/ohmyzsh/ohmyzsh/issues/6226#issuecomment-321682739

might be useful.

atakanarikan avatar Jan 29 '20 09:01 atakanarikan

I also had this issue and changing the locale fixed it for me https://github.com/ohmyzsh/ohmyzsh/issues/7558#issuecomment-460812339

negebauer avatar Apr 04 '20 01:04 negebauer