2012-08-09 8 views
12

Esto podría ser un poco marginal, pero recientemente me mudé a zsh y tengo problemas para personalizar el intérprete de comandos de mi shell.zsh no vuelve a calcular el intérprete de comandos de shell

Parte de mi .zshrc se ve así:

# keeping this simple right now by just printing the date, but imagine this function would look for something specific when moving to a new directory each time 
function parse_special { 
    print $(date) 
} 

autoload -U colors && colors 
PS1="%{$fg[green]%}%[email protected]%m %{$fg[blue]%}%c %{$fg[yellow]%}%{$(parse_special)%} %{$reset_color%}%# " 

Cuando inicio terminal, todo se ve bien; mi petición de orden es lo que espero:

[email protected] ~ Wed Aug 8 22:56:22 PDT 2012 % 

Pero cuando cd I a otro directorio, parece que mi función parse_special no se llama de nuevo para volver a calcular mi mensaje personalizado (nótese la fecha no está cambiando):

[email protected] ~ Wed Aug 8 22:56:22 PDT 2012 % cd .ssh 
[email protected] .ssh Wed Aug 8 22:56:22 PDT 2012 % cd ../workspace 
[email protected] workspace Wed Aug 8 22:56:22 PDT 2012 % 

¿Hay alguna manera en que pueda decirle a zsh que recalcule el aviso cada vez que se lo muestre?

muchas gracias por cualquier sugerencia.


respuesta a cjhveal

Parece que PS1 no le gusta para ponerse por valores entre comillas sencillas. He intentado lo siguiente:

local tp1="%{$fg[green]%}%[email protected]%m%{$reset_color%}" 
PS1="${tp1}" 
print "PS1 set by tp1: ${PS1}" 
local tp2='%{$fg[green]%}%[email protected]%m%{$reset_color%}' 
PS1="${tp2}" 
print "PS1 set by tp2: ${PS1}" 

Y tengo esta salida

#inner stuff was green 
PS1 set by tp1: %{%}%[email protected]%m%{%} 
#everything was uncolored 
PS1 set by tp2: %{$fg[green]%}%[email protected]%m%{$reset_color%} 

También me gustaría añadir, en base a la sugerencia de cjhveal, esto es lo que literalmente intentado. Una vez más, las comillas simples parecen estar ensuciar las cosas

function parse_special {  
    print $(date) 
} 

autoload -U colors && colors 
local prompt_user='%{$fg[green]%}%[email protected]%m%{$reset_color%}' 
local prompt_root='%{$fg[red]%}%[email protected]%m%{$reset_color%}' 
local prompt_dir='%{$fg[blue]%}%c%{$reset_color%}' 
local prompt_special='%{$fg[yellow]%}%{$(parse_special)%}%{$reset_color%}' 
PS1="${prompt_user} ${prompt_dir}${prompt_special}%# " 

Respuesta

14

me encontré con el mismo problema, mientras que la personalización de mi pronta en zsh.

Creo que esto sucede porque el intérprete de comandos interpola el valor en la cadena una vez, cuando se inicia el aviso. Las recargas posteriores tienen la cadena constante en su solicitud, no la interpolación de la subcapa.

En su lugar, coloque las líneas que implican subcapas en una variable definida con comillas simples. Luego, interpola esa variable en su lugar.

autoload -U colors && colors 

local parse_special='%{$fg[yellow]%}$(date)%{$reset_color%}' 

PS1="%{$fg[green]%}%[email protected]%m %{$fg[blue]%}%c ${parse_special} %# " 

Actualización: Agregando esto de la respuesta de ZyX para hacer una solución completa para esto. También es necesario añadir lo siguiente:

setopt promptsubst 

De hecho, sugeriría la extracción de cada parte de su pronta en una variable de este tipo, incluyendo un reset_color en cada uno. Hacerlo le permite cambiar el orden de los componentes de solicitud sin cambiar su implementación.

+0

gracias por la respuesta. Siento que esta es la solución correcta, pero todavía debo estar haciendo algo mal (ver la edición que hice en mi publicación original). Parece que no puedo usar comillas simples aquí. También puede explicar por qué es importante el uso de comillas simples en su respuesta? ¿var = "$ (do_stuff)" se trata de manera diferente que var = '$ (do_stuff)'? –

+0

Intenta eliminar el% {%} envuelto alrededor de la subcadena. No sé por qué, pero funciona para mí sin ellos. La diferencia entre comillas simples y dobles está en cómo la consola realiza la interpolación. var = "$ (do_stuff)" ejecuta inmediatamente la subshell e interpola el resultado una vez. Cuando utiliza comillas simples, esa subshell no se interpreta, y se mantiene como una constante literal hasta el momento en que se interpola en una cadena con comillas dobles. Luego se ejecuta. Básicamente, espera hasta que se renueve el indicador para ejecutar las subcapas. – cjhveal

+1

@cjhveal '% {' '%}' encierre el texto que zsh debería considerar de ancho cero (normalmente secuencias que le dicen al terminal que haga algo con el siguiente texto, como cambiar su color). Si encierra un texto de ancho distinto de cero, seguirá mostrándolo, pero con varios errores (por ejemplo, cuando completa zsh le dice al terminal que quiere cursor en cierta posición y coloca texto allí). non-zero-width-text%} 'hará que esta posición sea incorrecta y obtendrá un texto que sobrescribe el prompt y se colorea en el color de prompt). – ZyX

7

Usted es la mitad del camino para resolver este problema:

PS1='$(date)' 

le mostrará pronta $(date), pero

PS1='$(date)' 
setopt promptsubst 

le mostrará pronta Thu Aug 9 21:01:53 MSK 2012 (depende de $LANG y $LC_TIME, por supuesto) .

Por cierto, en el más reciente zsh que no es necesario utilizar %{$fg[blue]%} más, hay nn %F{blue} de primer plano, %K{blue} para el fondo, %f%k para restablecer ellos y algunos otros, ver man zshmisc, sección EXPANSION OF PROMPT SEQUENCES.

+0

ah, sí, estableciendo setopt promptsubst era la pieza que me faltaba. Muchas gracias. Voy a editar la respuesta anterior para agregar esa línea y hacer una respuesta completa de estos dos. Gracias de nuevo. –

Cuestiones relacionadas