2012-05-12 14 views
13

Vorrei mettere il mio ramo corrente git nel prompt ZSH su più righe. Tuttavia, questo incasina le due linee: mi piacerebbe che si allineino bene.Calcolo della lunghezza della stringa visibile dall'utente per il prompt zsh


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

dovrebbe essere:


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

Il ramo git viene afferrato da una funzione oh-my-zsh, git_prompt_info(), che mi dà il ramo, lo stato sporco, e un mazzo di pronta-sfugge per colorare le cose bene.

Come faccio a contare i caratteri che saranno visibilmente inseriti nel prompt ZSH - non le sequenze di escape prompt?

risposta

11

Supponendo che la stringa prompt di escape viene memorizzato in una variabile FOO, questo conta solo caratteri visibili dall'utente:

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

Questo viene da this .zshrc.

Questa è una spiegazione approssimativa del perché funziona, liberamente citando man zshexpn, sezione PARAMETER EXPANSION. Non sono sicuro al 100% dei dettagli, quindi, se lo stai utilizzando per sviluppare il tuo equivalente, leggi le sezioni pertinenti man zshall.

Lavorando dalla linea FOOLENGTH=${#${(S%%)FOO//$~zero/}}, abbiamo un numero di bit. Andando dall'interno verso l'esterno:

  1. $~zero: Il ~ assicura che zero, che abbiamo definito come '%([BSUbfksu]|([FB]|){*})', è trattata come un modello piuttosto che come una stringa semplice.

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

    Sostituire la più lunga partita possibile modello per l'espansione del nome del parametro da stringa repl

    Si noti che non abbiamo un repl; sostituiamo la corrispondenza più lunga possibile di pattern con nulla, rimuovendola così.
    (S%%)FOO esegue un'espansione su FOO con diversi flag impostati. Non lo seguo abbastanza.

  3. ${#${(S%%)FOO//$~zero/}}: ${#spec} sarà substitue la lunghezza in caratteri del risultato della sostituzione spec, se spec è una sostituzione. Nel nostro caso, spec è il risultato della sostituzione ${(S%%)FOO//$~zero/}; quindi questo in sostanza restituisce la lunghezza dei caratteri nel risultato dell'espressione regolare s/zero// su FOO, dove zero è il modello sopra.

+4

'(S)' rende corrispondenza non avido trasformando così “più lunga corrispondenza possibile” in “occorrenza più breve possibile” (senza di esso '{*}' in un modello si trasformerà cosa del genere '% F {blu}% M% F {giallo}% #% f' in solo'% # ', mentre dovrebbe trasformarlo in'% M% # '),' (%%) 'esegue un'espansione immediata sul stringa, seguendo le opzioni PROMPT_ *. Nota: questo metodo dovrebbe essere evitato se la stringa PROMPT contiene un comando con alcuni effetti collaterali: ad esempio, se si desidera utilizzarlo per contare la frequenza con cui viene visualizzato il prompt. La maggior parte delle volte non ne soffrirai. – ZyX

+0

E sì, tutti i flag '(*)' sono descritti nella sezione PARAMETER EXPANSION di 'man zshexpn'. – ZyX

+0

@ZyX Grazie. Ho visto la spiegazione di 'S' nella pagina' zshexpn', ma non ero sicuro di come fosse adattata. – simont

2

Non sei sicuro di come fare questo con i comandi incorporati zsh, ma le informazioni colore può essere spogliato con sed (come documentato here):

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

esempio

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

Quale sarebbe striscia tutte le sequenze di escape dalla stringa. La lunghezza è ora semplicemente:

echo $#plain_str 
+0

@beardtree: grazie per la modifica suggerita. – Thor

Problemi correlati