A idéia da minha configuração PS1
é mostrar algumas informações estendidas, como status do repositório do Mercurial ou do Git, tempo de execução do comando, etc. O prompt é dividido por duas linhas porque produz muitos caracteres para caber em uma única linha. Aqui está o meu PS1
no meu .bashrc
(não tenho certeza se todo o código-fonte é necessário aqui, espero que ajude):
function prompt_status {
local color_app="\e[1;38;5;214m"
local color_branch="\e[1;38;5;32m"
local color_revision="\e[0;38;5;64m"
if git rev-parse --is-inside-work-tree &> /dev/null; then
local branch="$(git rev-parse --abbrev-ref HEAD | tr -d '\n')"
local revision="$(git rev-parse HEAD | tr -d '\n')"
echo -ne $color_app"git "$color_branch"$branch "$color_revision"($revision)"
elif hg status &> /dev/null; then
local branch="$(hg branch | tr -d '\n')"
local revision_number="$(hg identify -n | tr -d '\n')"
local revision="$(hg parent --template '{node}' | tr -d '\n')"
echo -ne $color_app"hg "$color_branch"$branch "$color_revision"($revision_number:$revision)"
else
return
fi
echo -e " \e[0m"
}
function prompt_return_value {
RET=$?
if [[ $RET -eq 0 ]]; then
echo -ne "" #echo -ne "\e[32m$RET\e[0m"
else
echo -ne "\e[1;37;41m$RET\e[0m "
fi
}
function timer_start {
timer=${timer:-$SECONDS}
}
function timer_stop {
seconds_elapsed=$(($SECONDS - $timer))
unset timer
}
function prompt_seconds_elapsed {
local c;
local t=${seconds_elapsed}s
if [ $seconds_elapsed -ge 60 ]; then
c=196
t=$(format_seconds $seconds_elapsed)
elif [ $seconds_elapsed -ge 20 ]; then
c=214
elif [ $seconds_elapsed -ge 10 ]; then
c=100
elif [ $seconds_elapsed -ge 5 ]; then
c=34
elif [ $seconds_elapsed -ge 1 ]; then
c=22
else
return
fi
echo -ne "\e[0;38;5;${c}m${t} \e[0m"
}
function format_seconds {
((h=${1}/3600))
((m=(${1}%3600)/60))
((s=${1}%60))
printf "%02d:%02d:%02d\n" $h $m $s
}
trap 'timer_start' DEBUG
PROMPT_COMMAND=timer_stop
export PS1="\n\e[1;38;5;106m\u@\h \e[0;38;5;136m\w\[\e[0m\]\n\$(prompt_return_value)\$(prompt_seconds_elapsed)\$(prompt_status)\$ "
O problema é que o prompt parece quebrado quando uma janela de terminal tem pouca largura. Isso é o que eu recebo por 80 colunas:
username@some-very-long-hostname ~/tmp/d
06a14b06cac) $ 9866c9d0d26d2b27063a89ee1c330
É como embrulhar na segunda linha causando confusão total (veja o sinal $ no meio). Ele funciona quase perfeitamente para um número de coluna de terminal maior, digamos 120:
username@some-very-long-hostname ~/tmp/d
hg default (0:69866c9d0d26d2b27063a89ee1c3306a14b06cac) $
Também notei que adicionar mais texto ao final da linha do terminal causa um problema muito semelhante aos efeitos descritos para as 80 colunas acima. A pergunta é: bash
manipula novas linhas ou "muito longo" incorretamente para PS1
?
Obrigado.
UPDATE
Esta questão não é uma cópia exata de Por que meu prompt do bash está recebendo bug quando eu navego no histórico? . Depois de alguma discussão com @AdamKatz, parece que a saída de comprimento zero escapa de \[
e ']
funciona apenas quando são literalmente colocados na string PS1
, mas eles não parecem funcionar quando retornados de uma função que causa aparecem sem escape no terminal.