有人知道如何在 zsh 中的命令之间画线吗?
以下是 MobaXterm 的一个示例:
答案1
为了将当前PS1
提示延长一行,您可以使用以下方法之一。基本原理相同,但哪种方法最有效取决于您的终端仿真器、区域设置和字体设置。
打印一堆减号 ( -
) 或下划线 ( _
) 字符
setopt promptsubst
PS1=$'${(r:$COLUMNS::_:)}'$PS1
解释
- 该选项
promptsubst
允许在每次绘制提示时替换提示内的参数,在本例中为COLUMNS
。 - 参数扩展标志
r:$COLUMNS::_:
用下划线填充参数的右侧(在最后两个之间给出: :
),直到达到宽度$COLUMNS
。由于在这种情况下没有给出参数,因此只打印填充。 - 填充占据了终端的整个宽度,原始内容
PS1
会自动换行到下一行。因此无需添加额外的换行符。这也很重要,因为在某些情况下,显式换行符可能会导致提示覆盖输出的最后几行。(在我的情况下,当显式换行符之前的提示文本与终端宽度完全相同时,就会发生这种情况。)
这适用于每个终端仿真器(或控制台)、每个语言环境和每个字体。但看起来可能不太好:至少对于 minuses 来说,因为它们之间会有间隙(----
),对于 undercores 来说,它取决于字体。其他方法使用不同的方式在此基础上构建。
使用 zsh Prompt Escapes 加下划线以获得视觉效果
setopt promptsubst
PS1=$'%U${(r:$COLUMNS:: :)}%u'$PS1
解释:
%U
和之间的所有内容%u
都带有下划线。- 打印空格(将带有下划线)而不是下划线
由于它只使用下划线,因此它应该适用于大多数终端仿真器、语言环境和字体。一个可能的缺点是,水平线不会居中,而是位于输出行的非常低的位置,就在提示的下一行上方。
使用替代字符集进行线条绘制(又称方框绘制)
setopt promptsubst
PS1=$'%{\e(0%}${(r:$COLUMNS::q:)}%{\e(B%}'$PS1
解释:
%{...%}
告诉嘚仅期望不会实际移动光标的转义码\e(0
切换到备用字符集q
映射到备用字符集中的水平线\e(B
切换回常规字符集
这也应该适用于大多数终端仿真器(但可能不适用于控制台)、语言环境和字体。线条的粗细似乎因字体而异,甚至使用相同字体的终端仿真器也不同(在我的计算机上,使用 Terminus 字体的 urxvt 打印一条细线,而 roxterm 打印一条很粗的线)。
使用 Unicode 字符进行方框绘制
setopt promptsubst
PS1=$'${(r:$COLUMNS::\u2500:)}'$PS1
解释
- 使用 Unicode 字符 U+2500(“Box Drawing Light Horizontal”,
─
)进行填充。
这显然要求终端仿真器支持 Unicode 字符、具有所需字符的字体和 UTF-8 语言环境。但它也提供了几种可供选择的线条样式,如粗线 ( ━
) 或双线 ( ═
)。(请参阅Unicode 联盟官方代码表更多)
答案2
我认为该行被编码到提示中并通过下划线提示转义实现%U
:
PS1="%U %u
%~ "
您通常的提示在哪里%~
(使用 检查print $PS1
):
更棘手的是让行宽与终端一样宽。字符数存储在 中$COLUMNS
,因此我们构造一个由适当数量的空格组成的字符串,并用%U
/包围%u
:
drawline=""
for i in {1..$COLUMNS}; drawline=" $drawline"
drawline="%U${drawline}%u"
因为我们想在尺寸改变时更新长度,所以我们每次重新绘制之前都会重新定义提示,这可以通过在函数中放入代码来实现precmd()
:
precmd() {
drawline=""
for i in {1..$COLUMNS}; drawline=" $drawline"
drawline="%U${drawline}%u"
PS1="${drawline}
%~ "
}
瞧: