Count length of user-visible string for zsh prompt

后端 未结 2 539
面向向阳花
面向向阳花 2020-12-28 09:16

I\'d like to put my current git branch into my multi-line ZSH prompt. However, this messes up the two lines - I\'d like them to line up nicely.



        
2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-28 10:00

    Assuming that the prompt-escaped string is stored in a variable FOO, this will count only user-visible characters:

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

    This comes from this .zshrc.

    This is a rough explanation of why it works, liberally quoting from man zshexpn, section PARAMETER EXPANSION. I'm not 100% sure of the details, so, if you're using this to develop your own equivalent, read the relevant man zshall sections.

    Working from the line FOOLENGTH=${#${(S%%)FOO//$~zero/}}, we've got a number of bits. Going from the inside out:

    1. $~zero: The ~ ensures that zero, which we've defined as '%([BSUbfksu]|([FB]|){*})', is treated as a pattern rather than as a plain string.

    2. ${(S%%)FOO//$~zero/}: This matches ${name//pattern/repl}:

      Replace the longest possible match of pattern in the expansion of parameter name by string repl

      Note that we don't have a repl; we replace the longest possible match of pattern with nothing, thereby removing it.
      (S%%)FOO conducts an expansion on FOO with several flags set. I don't quite follow it.

    3. ${#${(S%%)FOO//$~zero/}}: ${#spec} will substitue the length in characters of the result of the substitution spec, if spec is a substitution. In our case, spec is the result of the substitution ${(S%%)FOO//$~zero/}; so this basically returns the length of characters in the result of the regular expression s/zero// on FOO, where zero is the pattern above.

提交回复
热议问题