如何在不导致终端重绘问题的情况下在 zsh 提示符中放置换行符?

15 zsh command-line osx-snow-leopard prompt

我正在尝试使用 zsh 提示修复一个小(但很烦人)的问题。我看到的问题是,当我在 GUI OS 环境中使用终端(例如,OS X 10.7.2 上的 Terminal.app 或 iTerm 2)并调整终端窗口的大小时,终端会重新绘制并带有额外提示.

我在一个干净的 .zshrc 上重现了这个问题,其中包含以下内容:

export PROMPT=">
"
Run Code Online (Sandbox Code Playgroud)

需要明确的是,这是一个两行文件。字符串中有一个文字换行符,我在几个(公认的旧)地方读过它是要走的路。这一直有效,直到我调整终端窗口的大小,此时我最终会得到重复的提示字符串。例如,如果我打开一个新窗口,我会看到(*我的光标被用作占位符):

Last login: Wed Jan 25 19:05:06 on ttys000
>
*
Run Code Online (Sandbox Code Playgroud)

然后当我调整窗口大小,使其更短时,我最终得到:

Last login: Wed Jan 25 19:05:06 on ttys000
>
>
>
>
*
Run Code Online (Sandbox Code Playgroud)

额外提示打印输出的数量似乎与我更改窗口大小的程度大致成正比——通常是垂直的。如果我从提示字符串中删除换行符,问题就会消失。

我尝试了各种方法,例如$(print ">\n"),或尝试将换行符包装在%{%}. 我假设这与这样一个事实有关,即换行符混淆了正在绘制的任何内容,而提示字符串实际上有多长,或者其他什么。这个问题可以解决还是我必须忍受它?

小智 19

这样的事情怎么样:

NEWLINE=$'\n'
PROMPT="Line1${NEWLINE}LINE2"
Run Code Online (Sandbox Code Playgroud)

  • 我比接受的答案更喜欢这个解决方案。它更便携,允许我在 zsh 和 bash 环境之间维护相同的脚本 (4认同)
  • 太棒了。又好又简单。例如,如果您只想在现有提示符前添加换行符,则可以`PROMPT="$NEWLINE$PROMPT"`。 (3认同)

小智 16

这个问题是由于 ZSH 如何在调整大小事件上重新打印提示,并且之前也让我很恼火。解决方案是制作$PROMPT单行并使用 precmd 打印提示的第一行。

所以在你的例子中,这只是:

precmd() { print ">" }
export PROMPT=""
Run Code Online (Sandbox Code Playgroud)

或者对于在打印语句中带有提示扩展的更复杂的示例,请使用以下-rP参数:

precmd() { print -rP "%~" }
export PROMPT="%# "
Run Code Online (Sandbox Code Playgroud)

如果您注册了多个 precmd,则需要使用add-zsh-hook precmd(请参阅参考资料man zshcontrib)。