Ho definito un prompt di bash (usando PROMPT_FUNCTION) in questo modo:
function get_hg_prompt_prefix() {
local APPLIED_COLOR=$1; shift
local UNAPPLIED_COLOR=$1; shift
local ALERT_COLOUR=$1; shift
local TEXTCOLOR=$1; shift
local mercurial_prompt_line="{{patches|join(:)|pre_applied(${APPLIED_COLOR})|post_applied(${TEXTCOLOR})|pre_unapplied(${UNAPPLIED_COLOR})|post_unapplied(${TEXTCOLOR})}\n\r}"
local mercurial_status_prompt="{ ${ALERT_COLOUR}{status}${TEXTCOLOR}}"
echo "$(hg prompt "${mercurial_prompt_line}" 2>/dev/null)$(hg prompt "${mercurial_status_prompt}" 2>/dev/null)"
}
function set_prompt() {
bright='\[[01m\]'
colors_reset='\[[00m\]'
HOSTCOLOR=${colors_reset}='\[[34m\]'
USERCOLOR=${colors_reset}='\[[01m\]'
TEXTCOLOR=${colors_reset}='\[[32m\]'
APPLIED_COLOR=${colors_reset}='\[[32m\]'
UNAPPLIED_COLOR=${colors_reset}='\[[37m\]'
ALERT_COLOUR=${colors_reset}='\[[31m\]'
hg_status="$(get_hg_prompt_prefix $APPLIED_COLOR $UNAPPLIED_COLOR $ALERT_COLOUR $TEXTCOLOR)"
ps1_prefix="${hg_status}$colors_reset($bright$(basename $VIRTUAL_ENV)$colors_reset) "
PROMPTEND='$'
PS1="${ps1_prefix}${USERCOLOR}\u${colors_reset}${TEXTCOLOR}@${colors_reset}${HOSTCOLOR}\h${colors_reset}${TEXTCOLOR} (\W) ${PROMPTEND}${colors_reset} "
}
PROMPT_COMMAND=set_prompt
In generale, questo mi dà un prompt multi-linea che mostra alcune informazioni sullo stato di hg e il mio virtualenv attuale, cercando (senza colore) in questo modo:
buggy-wins.patch
! (saas) user@computer (~) $
Il problema è che questo si sta rovinando con il calcolo della lunghezza del prompt (credo!) E causando strani problemi di avvolgimento dei terminali e posizionamento del cursore. Ad esempio, in un terminale a 80 caratteri, ecco il prompt che vedo (il carattere ** - circondato è la posizione del cursore):
~) $ **a**nis) crose@chris-rose (~
Nei terminali abbastanza larghi da visualizzare il prompt, il ritorno a capo avviene molto prima di quanto dovrebbe; ecco la maggior parte del testo che posso inserire nella prima riga del prompt in una finestra terminale di 108 caratteri (di nuovo, il ** segna la posizione del mio cursore):
**(**advanis) crose@chris-rose (~) $ sdkfjlskdjflksdjff
Quando la riga termina, sovrascrive il prompt. La seconda linea di input corre tuttavia fino al bordo del terminale, quindi si avvolge correttamente.
Quindi, chiaramente qualcosa sta rovinando la larghezza del prompt. Come posso fare bash per determinare la lunghezza della stringa PS1 non in base ai codici di escape ANSI, ma in base alla lunghezza effettiva visualizzata del prompt?