Ответ 1
Предполагая, что строка с экранированной подсказкой хранится в переменной FOO
, это будет считать только видимые пользователем символы:
FOO=$(git_prompt_info)
local zero='%([BSUbfksu]|([FK]|){*})'
FOOLENGTH=${#${(S%%)FOO//$~zero/}}
Это происходит от this .zshrc
.
Это грубое объяснение того, почему оно работает, свободно цитируя man zshexpn
, раздел PARAMETER EXPANSION
. Я не уверен на 100% деталей, поэтому, если вы используете это для разработки своего собственного эквивалента, прочитайте соответствующие разделы man zshall
.
Работая с линией FOOLENGTH=${#${(S%%)FOO//$~zero/}}
, у нас есть несколько бит. Идти изнутри:
-
$~zero
:~
гарантирует, чтоzero
, который мы определили как'%([BSUbfksu]|([FB]|){*})'
, рассматривается как шаблон, а не как простая строка. -
${(S%%)FOO//$~zero/}
: Это соответствует${name//pattern/repl}
:Замените максимально возможное совпадение шаблона при расширении имени параметра с помощью строкового repl
Заметим, что мы не имеем
repl
; мы заменяем самое длинное совпадениеpattern
ничем, тем самым удаляя его.
(S%%)FOO
выполняет разложение наFOO
с несколькими установленными флагами. Я не совсем понимаю это. -
${#${(S%%)FOO//$~zero/}}
:${#spec}
будет заменять длину в символах результата подстановкиspec
, еслиspec
является заменой. В нашем случаеspec
является результатом подстановки${(S%%)FOO//$~zero/}
; так что это в основном возвращает длину символов в результате регулярного выраженияs/zero//
наFOO
, гдеzero
- это шаблон выше.