2012-08-09 9 views
12

Questo potrebbe essere un po 'marginale, ma recentemente mi sono spostato su zsh e sto avendo problemi a personalizzare il prompt della shell.zsh non ri-calcolare il prompt della shell

Parte del mio .zshrc assomiglia a questo:

# 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%}%# " 

Quando lancio del terminale, tutto sembra a posto; il mio prompt è quello che mi aspetto:

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

ma quando ho cd a un'altra directory, sembra la mia funzione parse_special non è chiamato di nuovo per ricalcolare il mio prompt personalizzato (si noti la data non cambia):

[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 % 

C'è un modo in cui posso dire a zsh di ricalcolare il prompt ogni volta che lo sta per mostrare?

grazie mille per qualsiasi suggerimento.


risposta a cjhveal

Sembra PS1 non piace per avere istituito da valori indicati singoli. Ho provato quanto segue:

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}" 

e ottenuto questa uscita

#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%} 

Vorrei anche aggiungere, basata su suggerimento di cjhveal, ecco quello che ho provato letteralmente. Anche in questo caso, le virgolette singole sembrano essere scompigliare le cose

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}%# " 

risposta

14

Ho incontrato lo stesso problema durante la personalizzazione mio sollecito nel zsh.

Credo che questo accada perché la shell interpola il valore nella stringa una volta, quando il prompt viene inizializzato. I ricaricamenti successivi hanno la stringa costante nel prompt, non nell'interpolazione di sottotitoli.

Al contrario, inserire qualsiasi riga che includa subshells in una variabile definita con virgolette singole. Quindi interpola invece quella variabile.

autoload -U colors && colors 

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

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

Aggiornamento: aggiungere questo dalla risposta di ZyX per fare una soluzione completa per questo. È inoltre necessario aggiungere questo:

setopt promptsubst 

In realtà, vorrei suggerire l'estrazione di ogni parte del prompt in una variabile di questo tipo, tra cui un reset_color su ciascuno. Ciò consente di modificare l'ordine dei componenti prompt senza modificarne l'implementazione.

+0

grazie per la risposta. Credo che questa sia la soluzione giusta ma devo ancora fare qualcosa di sbagliato (vedi la modifica che ho apportato al mio post originale). Sembra che non posso usare le virgolette singole qui. Inoltre, puoi spiegare perché utilizzare le virgolette singole è importante nella tua risposta? è var = "$ (do_stuff)" trattato diversamente da var = '$ (do_stuff)'? –

+0

Prova a rimuovere il% {%} avvolto nella sottoshell. Non so perché, ma funziona per me senza di loro. La differenza tra virgolette singole e doppie è in come la shell esegue l'interpolazione. var = "$ (do_stuff)" esegue immediatamente la subshell e interpola il risultato una volta. Quando si usano le virgolette singole, quella subshell non viene interpretata e rimane come costante letterale fino al momento in cui viene interpolata in una stringa con virgolette doppie. Quindi viene eseguito. Essenzialmente, attende che il prompt venga aggiornato per eseguire le subshell. – cjhveal

+1

@cjhveal '% {' '%}' racchiude il testo che zsh dovrebbe considerare come larghezza zero (normalmente le sequenze che indicano al terminale di fare qualcosa con il testo seguente come cambiare il suo colore). Se si racchiude il testo con una larghezza diversa da zero, lo si visualizzerà comunque, ma con un numero di bug (ad esempio, quando si completa zsh dice al terminale che vuole il cursore su una determinata posizione e mette il testo lì. '% { non-zero-width-text%} 'renderà questa posizione errata e otterrai il testo che sovrascrive il prompt e sarà colorato nel colore del prompt). – ZyX

7

Tu sei la metà della strada per risolvere questo problema:

PS1='$(date)' 

vi mostrerà pronta $(date), ma

PS1='$(date)' 
setopt promptsubst 

vi mostrerà pronta Thu Aug 9 21:01:53 MSK 2012 (dipende $LANG e $LC_TIME, ovviamente) .

Tra l'altro, nella nuova zsh non è necessario utilizzare più %{$fg[blue]%}, c'è nos %F{blue} per il primo piano, %K{blue} per lo sfondo, %f%k per loro e pochi altri il ripristino, vedere man zshmisc, la sezione EXPANSION OF PROMPT SEQUENCES.

+0

ah, sì, setopt promptsubst era il pezzo che mi mancava. Molte grazie. Ho intenzione di modificare la risposta di cui sopra per aggiungere quella linea per fare una risposta completa da questi due. Grazie ancora. –

Problemi correlati