2012-05-12 11 views
13

Me gustaría poner mi rama actual git en mi línea de comandos ZSH de varias líneas. Sin embargo, esto arruina las dos líneas: me gustaría que se alineen muy bien.Longitud de la cuenta de la cadena visible por el usuario para el indicador de zsh


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

debería ser:


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

La rama git se agarró de una función oh-my-zsh, git_prompt_info(), que me da la rama, el estado sucio, y un montón de pronta-escapa a colorear las cosas muy bien.

¿Cómo cuento los caracteres que serán visiblemente insertados en el indicador ZSH - no las secuencias de escape de aviso?

Respuesta

11

Suponiendo que la cadena de petición-escapado se almacena en una variable FOO, esto contará únicamente caracteres de usuario visible:

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

Esto viene de this .zshrc.

Esta es una explicación aproximada de por qué funciona, citando libremente de man zshexpn, sección PARAMETER EXPANSION. No estoy 100% seguro de los detalles, por lo tanto, si está usando esto para desarrollar su propio equivalente, lea las secciones pertinentes de man zshall.

Trabajando desde la línea FOOLENGTH=${#${(S%%)FOO//$~zero/}}, tenemos un número de bits. Va de adentro hacia afuera:

  1. $~zero: El ~ asegura que zero, que hemos definido como '%([BSUbfksu]|([FB]|){*})', se trata como un patrón en lugar de como una cadena sin formato.

  2. ${(S%%)FOO//$~zero/}: Esto coincide con ${name//pattern/repl}:

    Vuelva a colocar la coincidencia más larga del patrón en la expansión del nombre del parámetro por la cadena repl

    Tenga en cuenta que no tenemos un repl; reemplazamos la coincidencia más larga posible de pattern con nada, y así lo eliminamos.
    (S%%)FOO lleva a cabo una expansión en FOO con varios indicadores establecidos. No lo sigo del todo.

  3. ${#${(S%%)FOO//$~zero/}}: ${#spec} se substitué la longitud en caracteres del resultado de la sustitución spec, si spec es una sustitución. En nuestro caso, spec es el resultado de la sustitución ${(S%%)FOO//$~zero/}; por lo que básicamente devuelve la longitud de los caracteres en el resultado de la expresión regular s/zero// en FOO, donde zero es el patrón anterior.

+4

'(S)' hace juego no expansivo convirtiendo así “coincidencia más larga” en “coincidencia más corta posible” (sin ella '{*}' en un patrón a su vez, algo así '% F {azul}% M% F {amarillo}% #% f' en solo'% # ', mientras que debería convertirlo en'% M% # '),' (%%) 'realiza la expansión de solicitudes en el cadena, siguiendo las PROMPT_ * opciones. Nota: este método debe evitarse si la cadena PROMPT contiene un comando con algunos efectos secundarios: por ejemplo, si desea usarlo para contar con qué frecuencia se muestra el mensaje. La mayoría de las veces no sufrirás de esto. – ZyX

+0

Y sí, todos los indicadores '(*)' se describen en la sección PARÁMETRO DE EXPANSIÓN de 'man zshexpn'. – ZyX

+0

@ZyX Gracias. Vi la explicación de 'S' en la página' zshexpn', pero no estaba seguro de cómo encajaba. – simont

2

No está seguro de cómo hacer esto con los comandos zsh incorporadas, pero la información de color se puede pelar con sed (como se documenta here):

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

por ejemplo,

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

Que eliminaría todas las secuencias de escape de la cadena. La longitud es ahora simplemente:

echo $#plain_str 
+0

@beardtree: gracias por la edición sugerida. – Thor

Cuestiones relacionadas