14

我想将我当前的git分支放入我的多行 ZSH 提示符中。然而,这弄乱了两条线——我希望它们能很好地排列。


┌─(simont@charmander:s000)─[master *]────────────────
───(~  )─┐  
└─(127:15:44)──                       ──(Sat,May12)─┘

应该:


┌─(simont@charmander:s000)─[master *]─────────(~  )─┐  
└─(127:15:44)──                       ──(Sat,May12)─┘

git分支是从一个oh-my-zsh函数中获取的git_prompt_info(),它为我提供了分支、脏状态和一堆提示符,可以很好地为事物着色。

如何计算将明显插入 ZSH 提示符的字符 - 而不是提示符转义序列?

4

2 回答 2

13

假设提示转义的字符串存储在一个变量FOO中,这将只计算用户可见的字符:

                                                                                                                                
FOO=$(git_prompt_info)                                                                                                                     
local zero='%([BSUbfksu]|([FK]|){*})'
FOOLENGTH=${#${(S%%)FOO//$~zero/}} 

这来自这个.zshrc

这是对其工作原理的粗略解释,自由引用man zshexpn, 部分PARAMETER EXPANSION。我不能 100% 确定细节,因此,如果您使用它来开发自己的等价物,请阅读相关man zshall部分。

从生产线FOOLENGTH=${#${(S%%)FOO//$~zero/}}开始,我们有很多位。由内而外:

  1. $~zero:~确保zero我们定义为'%([BSUbfksu]|([FB]|){*})'的 被视为模式而不是纯字符串。

  2. ${(S%%)FOO//$~zero/}:这匹配${name//pattern/repl}

    用字符串repl替换参数名扩展中模式的最长可能匹配

    请注意,我们没有repl; 我们将最长可能的匹配项替换为空pattern,从而将其删除。在设置了几个标志的情况下
    (S%%)FOO进行扩展。FOO我不太明白。

  3. ${#${(S%%)FOO//$~zero/}}:如果是${#spec}替换,将替换替换结果的字符长度。在我们的例子中,是替换的结果;所以这基本上返回了正则表达式on结果中的字符长度,上面的模式在哪里。specspecspec${(S%%)FOO//$~zero/}s/zero//FOOzero

于 2012-05-12T14:04:08.117 回答
2

不知道如何使用内置 zsh 命令执行此操作,但可以使用 sed 剥离颜色信息(如此所述):

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"

例如

plain_str=$(git_prompt_info | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")

这将从字符串中删除所有转义序列。现在的长度很简单:

echo $#plain_str
于 2012-05-12T15:04:29.000 回答