30

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 Answers 2

21

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).

2
  • 1
    For newbies like myself, you can see what -rP means here: 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
    Commented Oct 25, 2012 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. Commented Jan 30, 2013 at 22:51
50

How about something like this:

NEWLINE=$'\n'
PROMPT="Line1${NEWLINE}LINE2"
5
  • 4
    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
    Commented Nov 5, 2015 at 3:11
  • This solution worked better for me.
    – Praym
    Commented Jun 1, 2020 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".
    – Kevin E
    Commented Nov 4, 2021 at 15:37
  • ...or as a single assignment PROMPT=$'Line1\nLINE2', or if parameter expansion is needed PROMPT="$(uname)"$'\n'"$CPUTYPE" etc., or use an intermediate array lines=(Line1 LINE2); PROMPT="${(F)lines}"
    – Carl
    Commented Sep 16, 2023 at 14:38
  • This solution is much more cleaner. I was searching for why \n didn't work inside "s but apparently when added inside 'it works. Some ZSH quirk is it? Commented Mar 18 at 5:10

You must log in to answer this question.