How can I put a newline in my zsh prompt without causing terminal redraw issues?

12

4

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?

user45283

Posted 2012-01-26T03:21:11.613

Reputation:

Answers

13

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

Posted 2012-01-26T03:21:11.613

Reputation: 146

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 – 2012-10-25T20:51:50.783

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 – 2013-01-30T22:51:09.980

10

How about something like this:

NEWLINE=$'\n'
PROMPT="Line1${NEWLINE}LINE2"

Đức Thanh Nguyễn

Posted 2012-01-26T03:21:11.613

Reputation: 211

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 – 2015-11-05T03:11:46.970