Як виправити підказку підказки з кольоровим баштом?


9

Я визначив підказку bash (використовуючи PROMPT_FUNCTION) так:

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

Взагалі, це дає мені багаторядковий запит, який відображає інформацію про статус hg, а також мій поточний virtualenv, виглядаючи (без кольору) так:

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

Проблема полягає в тому, що це вкручування з обчисленням довжини підказки (я думаю!) І спричинення дивних проблем із загортанням терміналів та розміщення курсору. Наприклад, у 80-знаковому терміналі, я бачу підказку (** - оточений символ - це розташування курсору):

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

На терміналах, досить широких для відображення підказки, загортання рядків відбувається набагато раніше, ніж слід; ось найбільше тексту, який я можу вмістити в першому рядку підказки у вікні терміналу, що має 108 знаків (знову ж таки, ** позначає місце розташування мого курсору):

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

Коли рядок загортається, він замінює підказку. Однак другий рядок вводу проходить вправо до краю терміналу, а потім правильно завертається.

Отже, явно щось псується з шириною підказки. Як я можу змусити bash визначити довжину рядка PS1 не за кодами аварійних відбітків ANSI, а відповідно до фактично відображеної довжини підказки?

Відповіді:


21

bashвикористовує \[ \]для визначення "відображеної довжини": текст між цими двома переходами вважається недрукованим та не враховується загальною довжиною; все інше є.

Здається, що у ваших змінних є проблема: bright='\[[01m\]'насправді не міститься символ ESC, тому [01mвін друкується як звичайний текст, але не враховується в довжину. Це повинно бути '\[\e[01m\]'. Те саме для всіх інших змінних.


Пов'язані:

  • в Bash, ви можете помістити \$(hg_status)в $PS1безпосередньо, без необхідності окремо PROMPT_COMMAND.

1
Це забезпечує часткове виправлення; довжина рядка тепер виявлена ​​належним чином, але це не виправляє проблеми з написанням загортання першого рядка над запитом.
Кріс Р

1
Кріс Р: Я спробував ваш підказку і просто замінив все '\[[на '\[\e[працював у баш на Ubuntu 12.04. Уникнення кольорів (та деяких інших деталей, що не стосуються швидкого розміру) з \[...\]мені теж допомогло, але у мене є набагато-набагато складніший PS1, ніж ви (з правильним вирівнюванням тексту в тому ж рядку, що і підказки, і текстом у нижньому правому куті куточок). Це виправляло як проблеми раннього обгортання, так і проблеми, що перекриваються.
TWiStErRob
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.