![Como faço para corrigir o empacotamento do prompt colorido do bash?](https://rvso.com/image/1259391/Como%20fa%C3%A7o%20para%20corrigir%20o%20empacotamento%20do%20prompt%20colorido%20do%20bash%3F.png)
Eu defini um prompt bash (usando PROMPT_FUNCTION) assim:
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
Em geral, isso me fornece um prompt de várias linhas que exibe algumas informações de status do hg, bem como meu virtualenv atual, parecido (sem cor) assim:
buggy-wins.patch
! (saas) user@computer (~) $
O problema é que isso está atrapalhando o cálculo do comprimento do prompt (eu acho!) E causando problemas estranhos de quebra de terminal e posicionamento do cursor. Por exemplo, em um terminal de 80 caracteres, aqui está o prompt que vejo (o caractere ** cercado é a localização do cursor):
~) $ **a**nis) crose@chris-rose (~
Em terminais largos o suficiente para exibir o prompt, a quebra de linha ocorre muito mais cedo do que deveria; aqui está o máximo de texto que consigo caber noprimeirolinha do prompt em uma janela de terminal com 108 caracteres (novamente, ** marca a localização do meu cursor):
**(**advanis) crose@chris-rose (~) $ sdkfjlskdjflksdjff
Quando a linha termina, ela substitui o prompt. A segunda linha de entrada vai até a borda do terminal e, em seguida, é quebrada corretamente.
Então, claramente algo está atrapalhando a largura do prompt. Como posso fazer com que o bash determine o comprimento da string PS1 não de acordo com os códigos de escape ANSI, mas de acordo com o comprimento real exibido no prompt?
Responder1
bash
usa \[
\]
para determinar o "comprimento exibido": o texto entre esses dois escapes é considerado não imprimível e não contado no comprimento total; todo o resto é.
Parece haver um problema com suas variáveis: bright='\[[01m\]'
na verdade, não inclui um caractere ESC, portanto, [01m
é impresso como texto normal, mas não é contado no comprimento. Deveria ser '\[\e[01m\]'
. O mesmo para todas as outras variáveis.
Relacionado:
- no Bash, você pode colocar
\$(hg_status)
diretamente$PS1
, sem a necessidade de um arquivoPROMPT_COMMAND
.