每个命令后的zsh换行提示

30

我可以配置提示符以在每个命令后显示一个新行吗?

举个例子,在下面的屏幕截图中,我运行了cat .zshrc。我想在命令的最后输出行. ~/.zsh_aliases~ $之间有一个新行。

输入图像描述

10个回答

49

编辑~/.zshrc文件并添加以下代码:precmd() { print "" }。这将在渲染PROMPT之前简单地打印一行空白。


谢谢!完美的解决方案。 - orschiro
9
这个方法是可以的,但问题在于每次提示符出现之前都会打印一个新行,即使您刚启动了 shell!有没有什么解决方法? - Sethen
2
@Sethen,我知道现在已经过去两年了,但是你的问题很常见。我已经对这个答案进行了编辑(它仍然是一个顶级搜索结果),并解决了这个问题。 - user926352
@Ben,你的编辑还没有被接受,能否请你分享一下你的解决方案? - Vinay Nagaraj
1
跳过第一个提示符上的空行的技巧是将 precmd() { print "" } 包装在 precmd() { … } 中。请参见我的回答,其中包含一些解释。 - Chris Morgan

21

某些现有解决方案的一种变体,我发现比使用神奇变量和条件语句更为简洁:

precmd() {
    precmd() {
        echo
    }
}

这会在每个提示符前面放置一个空行,除了第一个提示符之外:所有第一个precmd调用所做的只是将precmd替换为调用echo的函数。


完美的答案!是否有可能在顶部不需要换行符时为“clear”做出异常处理? - Yashank
我不认为通常是这样的。你可以将clear别名到某个会以这种方式重新定义precmd的东西,但此时使用一个魔术变量和条件可能更清晰。你可能还需要在zle中以某种方式改变Ctrl-L的行为,以便它也进行这种调整。我不确定该如何实现。 - Chris Morgan

13

另一种方法是在〜/ .zshrc中设置自定义提示符,其中包含一个换行符。例如:

另一种方法是通过在〜/ .zshrc中设置一个自定义提示符,来包含一个换行符。例如:

autoload -Uz promptinit
promptinit

PROMPT="
%n@%m:%~ $ "

1
这就是我最终采用的方法,以避免在每个新提示之前出现新行。 - Sethen

8
接受的答案(由@abid-h-mujtaba编写)总是打印一个换行符,即使在shell的第一次加载时也是如此。我提交了一个编辑,但出于某种原因没有被接受。
这是我在个人点文件中使用的内容(请参见zshrc中的“窗口配置”):
function precmd() {
    # Print a newline before the prompt, unless it's the
    # first prompt in the process.
    if [ -z "$NEW_LINE_BEFORE_PROMPT" ]; then
        NEW_LINE_BEFORE_PROMPT=1
    elif [ "$NEW_LINE_BEFORE_PROMPT" -eq 1 ]; then
        echo "\n"
    fi
}

1
“echo "\n"” 对我来说似乎打印了两个空行,但是“echo ""”效果很好。 - Saad
非常感谢您的回答。 - Santiago
适用于“重置”、“清除”和命令之间,但在CTRL+l之后不会添加换行符。 - jmg

5

以下是有效的内容:

导出 PS1='
其他文本-嗯$'


这个答案对那些试图在提示字符串中插入换行符的人很有帮助。我的兴趣是在美元符号$字符之前插入一个换行符。这将使提示文本单独一行,实际的$提示符在新的一行上。 - Sixto Saez

3

用户926352

被@abid-h-mujtaba撰写的被采纳答案总是会打印一个换行符,即使在shell的第一次加载时也是如此。我提交了一个编辑,但不知何故没有被接受。这是我在个人dotfiles中使用的内容(请参见zshrc中的“Window Configuration”):function precmd() { #在提示符之前打印一个换行符,除非它是#进程中的第一个提示符。 if [ -z "$NEW_LINE_BEFORE_PROMPT" ]; then NEW_LINE_BEFORE_PROMPT=1 elif [ "$NEW_LINE_BEFORE_PROMPT" -eq 1 ]; then echo "\n" fi }

我使用了这个答案,但是不想在清屏后输入一个新行。因此我添加了:

alias clear="unset NEW_LINE_BEFORE_PROMPT && clear"

这只是一个代替clear函数的小技巧,同时也会取消新行变量。

注意: 以上建议已经进行了编辑,因为我将一个包含取消变量和清空内容的函数赋给了clear函数。这使得函数递归调用,最终超出了嵌套函数的极限。您可以使用以下代码,它更加简单和安全。如果在编辑之前有人发现这个问题,非常抱歉。


我也做了同样的事情,但还加上了重置。 - Daniel

2

我知道这篇文章有点旧了,但我找到了一种方法,虽然不是很完美,但我想分享一下:

function precmd {
    if [[ "$NEW_LINE" = true ]] then
        if [[ "${ADD_NEW_LINE}" = true ]] then
            PROMPT=$'\n'"${PROMPT}"
            ADD_NEW_LINE=false
        fi
    else
        PROMPT="${PROMPT}"
        NEW_LINE=true
        ADD_NEW_LINE=true
    fi
}

希望能对您有所帮助。

1

要在提示之间仅打印一个换行符:

precmd() $funcstack[1]() echo

或者如果你想使用多个precmd钩子:
autoload -Uz add-zsh-hook
_precmd_newline_between_prompts() $funcstack[1]() echo
add-zsh-hook precmd _precmd_newline_between_prompts

解释:

在zsh中,简单函数的大括号是可选的,因此如果不清楚,第一种方法等同于这个:

precmd() {
  $funcstack[1]() {
    echo
  }
}

$funcstack[1]是一个特殊的zsh参数,包含了调用者/外部函数的名称。

在第一次调用(第一个提示之前),内部方法$funcstack[1]() echo不会运行,但会重新定义外部方法,因此在进一步调用(在额外提示之前)时只会打印一个换行符。


1

使用oh-my-zsh、git支持和ZSH Powerlevel9k主题的zsh,在Ubuntu 18.04上安装方法如下:https://linuxhint.com/install_zsh_shell_ubuntu_1804/

要在新行打开提示符,请执行以下操作:

/usr/share/powerlevel9k/powerlevel9k.zsh-theme

请查找 left_prompt_end() 函数。

在原始代码中,该函数如下所示:

# End the left prompt, closes the final segment.
left_prompt_end() {
  if [[ -n $CURRENT_BG ]]; then
    echo -n "%k%F{$CURRENT_BG}$(print_icon 'LEFT_SEGMENT_SEPARATOR')"
  else
    echo -n "%k"
  fi
  echo -n "%f$(print_icon 'LEFT_SEGMENT_END_SEPARATOR')"
  CURRENT_BG=''
}

只需添加一个换行符命令。现在函数应该看起来像这样:

# End the left prompt, closes the final segment.
left_prompt_end() {
  if [[ -n $CURRENT_BG ]]; then
    echo -n "%k%F{$CURRENT_BG}$(print_icon 'LEFT_SEGMENT_SEPARATOR')\n"
  else
    echo -n "%k"
  fi
  echo -n "%f$(print_icon 'LEFT_SEGMENT_END_SEPARATOR')"
  CURRENT_BG=''
}

以下行内容已更改:

以下是更改后的内容:

echo -n "%k%F{$CURRENT_BG}$(print_icon 'LEFT_SEGMENT_SEPARATOR')"

To:

echo -n "%k%F{$CURRENT_BG}$(print_icon 'LEFT_SEGMENT_SEPARATOR')\n"

新的一行提示: 在此输入图像描述


新行上有一个额外的空格。您能告诉我如何删除这个额外的行吗? - Bikram Kumar

0
很多上面的答案确实有效,但有一些注意事项,比如启动时会出现烦人的换行符和终端清除时的换行符。
这个解决方案可以解决所有问题(希望如此)。
在你的.zshrc文件中添加以下内容。
precmd() {
    precmd() {
        echo
    }
}

这将在每个命令后回显一个新行,但不会在启动时回显

但我们仍然有另一个问题 - 当终端被清除时,会回显一个换行符。为了解决这个问题,将别名'clear'设置为:

alias clear="precmd() {precmd() {echo }} && clear"

对我来说,“Ctrl + L”会清除屏幕,但不带换行符。但是如果有人遇到问题,只需将此代码添加到您的.zshrc文件中。

bindkey -s '^L' 'clear^M'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接