Como impedir que as cores do prompt do bash escapem

3

Estou tentando configurar o bash para exibir o branch git atual, baseado no exemplo , mas não posso descobrir como conseguir bash para parar de escapar as cordas de cores. Tudo que eu tento resulta nas seqüências de cores que estão sendo emitidas na linha de prompt.

Meu prompt é assim:

valorin@gandalf:~/workspace/wyoa (\[3[0;31m\]master\[3[00m\])$

A seção relevante em .bashrc :

##
# Custom Git Branch name in prompt
##
function git_prompt {
    if !  git rev-parse --git-dir > /dev/null 2>&1; then
        return 0
    fi

    git_branch=$(git branch 2>/dev/null| sed -n '/^\*/s/^\* //p')

    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        if git diff --quiet 2>/dev/null >&2; then
            echo " (\[3[0;31m\]$git_branch\[3[00m\])"
        else
            echo " (\[3[0;33m\]$git_branch\[3[00m\])"
        fi
    else
        if git diff --quiet 2>/dev/null >&2; then
            echo " ($git_branch)"
        else
            echo "($git_branch*)"
        fi
    fi
}


if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[3[01;32m\]\u@\h\[3[00m\]:\[3[01;34m\]\w\[3[00m\]$(git_prompt)$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(git_prompt)$ '
fi

Qualquer ajuda seria apreciada.

    
por Stephen RC 14.07.2012 / 03:07

1 resposta

3

Você não pode ter uma função que produza texto e cor, no prompt do bash. Tudo o resultado da função é levado literalmente. Eu sugiro ir de uma maneira diferente.

Em primeiro lugar, o que o prompt tenta fazer, é verificar se você está em uma árvore git, e em caso afirmativo, adicione um colorido (ramo) para o prompt. Em vez de verificar toda vez que o prompt é impresso, você realmente só precisa fazer essa verificação sempre que você mudar de diretório, para que possamos substituir os três únicos comandos que podem mudar de diretório para definir a variável git_branch para o nome da ramificação atual, se houver.

cd() {
    builtin cd "$@" || return
    git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
pushd() {
    builtin pushd "$@" || return
    git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
popd() {
    builtin popd "$@" || return
    git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}

Em seguida, verifique se o stderr é um terminal e defina as cores com tput

user_color= dir_color= git_color= reset=
if [[ -t 2 ]]; then
    user_color=$(tput setaf 2; tput bold)
    dir_color=$(tput setaf 4; tput bold)
    reset=$(tput sgr0)
fi

E uma função que gera uma das duas cores com base no fato de haver ou não alterações

_git_color() {
    [[ $git_branch && -t 2 ]] || return
    if git diff --quiet >/dev/null 2>&1; then
        tput setaf 1
    else
        tput setaf 3
    fi
}

Agora, junte o prompt. Isso é um pouco incômodo, pois algumas variáveis devem ser expandidas na atribuição (agora), enquanto algumas devem ser expandidas quando o prompt é impresso, então precisamos alternar aspas, além de ficar bastante longo. Usar uma matriz para isso deve ajudar a manter a visão geral

prompt=(
    "\[$user_color\]" '\u@\h' "\[$reset\]"
    : "\[$dir_color\]" '\w' "\[$reset\]"

    '${git_branch:+ (}'
    '\[$(_git_color)\]' '$git_branch' "\[$reset\]"  
    '${git_branch:+)}'

    '$ '
)

Eu omiti as coisas do debian_chroot aqui, eu nunca precisei disso, você pode, claro, adicionar isso se quiser. Por fim, junte-se à matriz de prompt e limpe as variáveis que não precisamos mais.

printf -v PS1 %s "${prompt[@]}"
unset user_color dir_color reset prompt
    
por geirha 14.07.2012 / 10:35

Tags