25

I'm trying to fix a minor (but annoying) issue with my zsh prompt. The problem I'm seeing is that when I'm using a terminal in a GUI OS environment (for example, Terminal.app or iTerm 2 on OS X 10.7.2) and resize the terminal window, the terminal is redrawn with extra prompts.

I've reproduced the issue on a clean .zshrc that contains the following:

export PROMPT=">
"

To be clear, that's a two-line file. There is a literal newline in the string, which I've read in several (admittedly old) places is the way to go. This works until I resize the terminal window, at which point I end up with duplicate prompt strings. For example if I open a new window, I see (* being used a placeholder for my cursor):

Last login: Wed Jan 25 19:05:06 on ttys000
>
*

Then when I resize the window, making it shorter, I end up with:

Last login: Wed Jan 25 19:05:06 on ttys000
>
>
>
>
*

The number of extra prompt printouts seems roughly proportional to how much I change the window size -- usually vertically. If I remove the newline from the prompt string, the problem goes away.

I've tried various things, like $(print ">\n"), or trying to wrap the newline in %{%}. I'm assuming this has to do with the fact that newline confuses whatever is drawing w.r.t how long the prompt string actually is, or something. Is this problem fixable or do I just have to live with it?

2 Answers2

39

How about something like this:

NEWLINE=$'\n'
PROMPT="Line1${NEWLINE}LINE2"
  • 3
    I like this solution better than the accepted answer. it is more portable, and allows me to maintain the same script between my zsh and bash environments – verboze Nov 05 '15 at 03:11
  • This solution worked better for me. – Praym Jun 01 '20 at 21:13
  • 3
    Bravo. Nice and simple. If you just want to, say, prepend a newline to the existing prompt, you can `PROMPT="$NEWLINE$PROMPT"`. – TheDudeAbides Nov 04 '21 at 15:37
20

This problem is due to how ZSH reprints the promt on resize events and has also annoyed me before. The solution is to make $PROMPT single-line and print the first line of the prompt using a precmd.

So in your example that would simply be:

precmd() { print ">" }
export PROMPT=""

or for a more sophisticated example with prompt expansion in the print statement use the -rP parameters:

precmd() { print -rP "%~" }
export PROMPT="%# "

If you have more than one precmd registered you need to use add-zsh-hook precmd (see man zshcontrib).

K-os
  • 316
  • 2
  • 5
  • 1
    For newbies like myself, you can see what -rP means here: http://www.cs.elte.hu/zsh-manual/zsh_17.html. It appears that `print` is a ZSH-specific command, and Googling "linux print" doesn't give you very good results. – MikeWyatt Oct 25 '12 at 20:51
  • `print` is part of zsh. You can see the help for it in `man zshbuiltins`. Bash has its own equivalent, but I'm not sure they're compatible. – Jim Stewart Jan 30 '13 at 22:51