PS1
我的设置包含.zshrc
多个 ANSI 转义序列。等效的定义在 Bash 中运行良好,但在 Zsh (v5.8.1) 中它似乎会导致 shell 错误地计算提示符的宽度。因此,当输入较长的命令时,命令行突然消失,我正在盲打。在某些情况下,它会导致光标被放置在提示后的下一行,即使PS1
不包含换行符。
我已经在使用\001…\002
转义序列readline 使用它们来调整每个 ANSI 转义序列的长度计算。不幸的是,这对于 Zsh 来说似乎还不够(在下面的例子中,他们似乎没有任何效果,但在我真实的、更复杂的情况下PS1
,他们似乎改善了情况有些, 至少)。
下面是一个演示该问题的示例(注释强调了我认为需要用 括起来的 ANSI 转义序列部分\001…\002
):
PS1=$'\001\e[38;2;1;1;1m\e[48;5;250m\002}\001\e[38;5;250m\e[48;2;1;1;1m\002} '
# \001--------------------------\002 \001--------------------------\002
有了这个提示,并使用 80 列终端,在我输入 25 个字符后,包括提示在内的整个命令都会消失。使用退格键不会使字符重新出现,而是使光标转到上一行。
对于此演示,我禁用了 shell 的所有其他自定义。
(实际上我正在使用nf-pl-left_hard_divider
U+E0B0,来自书呆子字体而不是}
s,但这不会影响问题。)
我究竟做错了什么?如何在 Zsh 提示符定义中使用 ANSI 转义序列?
答案1
在 中zsh
,您可以使用%{
并%}
提示转义符。从info zsh 'prompt expansion'
:
%{...%}
包含一个字符串作为文字转义序列。大括号内的字符串不应更改光标位置。支撑对可以嵌套。% 和 { 之间的正数值参数按照下面 %G 的描述进行处理。
因此,除了PS1='%{\e[...m%}'
您不需要在 zsh 中硬编码转义序列之外,因为它有自己的提示扩展运算符来实现大多数视觉效果。
例如,要将256 调色板中的F
背景颜色设置为 RGB#010101
并将背景颜色设置为 250,您可以执行以下操作:B
PS1='%F{#010101}%K{250}Text%f%k%# '
您可以使用print -P
它也进行提示扩展,以查看正在生成哪些相应的转义序列:
$ print -rP '%F{#010101}%K{250}' | sed -n l
\033[38;2;1;1;1m\033[48;5;250m$
甚至还有一个模块可以为不支持真彩色转义序列(但支持 256 调色板)的终端上的规范zsh/nearcolor
提供最接近的颜色:#RRGGBB
$ zmodload zsh/nearcolor
$ print -rP '%F{#010101}%K{250}' | sed -n l
\033[38;5;16m\033[48;5;250m$