如何在 zsh shell 中的命令之间画一条线

如何在 zsh shell 中的命令之间画一条线

有人知道如何在 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 Horizo​​ntal”,)进行填充。

这显然要求终端仿真器支持 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}
%~ "
}

瞧:

在此处输入图片描述

相关内容