Renk bash istemi sarmamı nasıl düzeltirim?


9

Ben böyle bir bash istemi (PROMPT_FUNCTION kullanarak) tanımladık:

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

Genel olarak, bu bana bazı hg durum bilgilerinin yanı sıra geçerli virtualenv'imi görüntüleyen çok renkli bir komut istemi verir, (renksiz) şöyle görünür:

buggy-wins.patch
 ! (saas) user@computer (~) $ 

Sorun, bu istemin uzunluğunun hesaplanması ile vida (sanırım!) Ve garip terminal sarma sorunlarına ve imleç yerleştirmeye neden oluyor. Örneğin, 80 karakterlik bir terminalde, gördüğüm komut istemi (** - çevrili karakter imleç konumudur):

~) $ **a**nis) crose@chris-rose (~

İstemi görüntüleyecek kadar geniş terminallerde, satır sarma gerektiğinden çok daha erken gerçekleşir; 108 karakterlik bir terminal penceresindeki istemin ilk satırına sığabileceğim en fazla metin (yine, ** imlecimin konumunu işaretler):

 **(**advanis) crose@chris-rose (~) $ sdkfjlskdjflksdjff

Satır bittiğinde, istemin üzerine yazılır. Bununla birlikte, ikinci girdi satırı terminalin kenarına doğru ilerler ve sonra doğru bir şekilde sarılır.

Yani, açıkça bir şey istemin genişliği ile karıştırıyor. Bash'nin PS1 dizesinin uzunluğunu ANSI çıkış kodlarına göre değil, istemin görüntülenen gerçek uzunluğuna göre belirlemesine nasıl neden olabilirim?

Yanıtlar:


21

bash\[ \]"görüntülenen uzunluğu" belirlemek için kullanır : bu iki çıkış noktası arasındaki metin yazdırılamaz ve toplam uzunluk olarak sayılmaz; diğer her şey.

Değişkenlerinizle ilgili bir sorun var gibi görünüyor: bright='\[[01m\]'aslında bir ESC karakteri içermiyor, bu nedenle [01mnormal metin olarak yazdırılıyor, ancak uzunluk olarak sayılmıyor. Olmalı '\[\e[01m\]'. Diğer tüm değişkenler için aynıdır.


İlişkili:

  • in Bash, you can put \$(hg_status) to $PS1 directly, without the need for a separate PROMPT_COMMAND.

1
That provides a partial fix; the line length is detected properly now, but it doesn't fix the problem with the first line wrap writing over the prompt.
Chris R

1
Chris R: I tried your prompt and just replacing all '\[[ with '\[\e[ worked in bash on Ubuntu 12.04. Escaping colors (and some other irrelevant-to-prompt-size parts) with \[...\] helped me too, but I have much-much-much more complex PS1 than you (with right aligned text on the same line as prompt and text in the lower right corner). It fixed both the early wrapping and the overlapping wrapping problems.
TWiStErRob
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.