虽然您的想法值得赞扬,但您遇到的问题是您的
LEFT
和
RIGHT
包含ANSI转义序列(用于颜色),这些序列应该是零宽字符,但如果您天真地使用
$#name
或
${(l:expr:)name}
,它们仍然会被计算为字符串的长度。
此外,从风格上讲,最好使用Zsh的内置
提示扩展,它将许多人们可能想在其提示中看到的常见内容包装在短百分号转义序列中。特别是,有内置的颜色序列,因此您不需要依赖非标准的
$fg[blah]
。
下面是一个近似于您的提示符的示例,以我喜欢的编码风格编写... 不完全一样,我使每个部分都非常详细,以便更易理解(希望如此)。在剥离颜色转义序列并执行提示扩展后,左侧和右侧预提示的长度被计算出来,这给出了正确的显示长度(我不可能在几分钟内完成;我从
pure
中复制了表达式)。
precmd(){
local preprompt_left="%F{cyan}%n@%m %F{green}%~"
local preprompt_right="%F{yellow}%D{%I:%M %p}%f"
local preprompt_left_length=${#${(S%%)preprompt_left//(\%([KF1]|)\{*\}|\%[Bbkf])}}
local preprompt_right_length=${#${(S%%)preprompt_right//(\%([KF1]|)\{*\}|\%[Bbkf])}}
local num_filler_spaces=$((COLUMNS - preprompt_left_length - preprompt_right_length))
print -Pr $'\n'"$preprompt_left${(l:$num_filler_spaces:)}$preprompt_right"
}
PROMPT="$ "
编辑: 在某些终端仿真器中,打印恰好$COLUMN
个字符可能会换行。在这种情况下,请使用以下内容替换相应的行:
local num_filler_spaces=$((COLUMNS - preprompt_left_length - preprompt_right_length - 1))
编辑结束。
这个非常可定制,因为你几乎可以在preprompt_left
和preprompt_right
中放入任何东西,仍然可以得到正确的长度 - 只需记住使用提示转义序列用于零宽度序列,例如,%F{}%f
表示颜色,%B%b
表示粗体等。再次阅读有关提示扩展的文档:http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html。
注意:您可能会注意到%D{%I:%M %p}
扩展为像11:35 PM
这样的内容。那是因为我想使用%P
来获取pm
,但并不是每个strftime
实现都支持%P
。最坏的情况是:如果您真的想要小写但不支持%P
,请使用原始命令替换$(date +'%I:%M %P')
。
此外,我使用
%~
而不是
%/
,这样你会得到
~/Desktop
而不是
/c/Users/johndoe/Desktop
。有些人喜欢,有些人不喜欢。然而,正如我所说,这很容易自定义。