如何修复我的bash提示换行?


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

通常,这会给我多行提示,显示一些汞状态信息以及我当前的virtualenv,看起来(无颜色)如下:

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

问题是,这与提示长度的计算(我认为!)有关,并导致奇怪的终端换行问题和光标放置。例如,在一个80字符的终端中,这是我看到的提示(**包围的字符是光标位置):

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

在宽度足以显示提示的终端中,换行发生的时间要早​​得多;这是我可以在108字符宽的终端窗口中的提示第一行显示的最多文字(同样,**表示我的光标位置):

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

该行结束时,它将覆盖提示。输入的第二行直接到终端的边缘,然后正确换行。

因此,很明显,提示的宽度有些混乱。如何使bash不根据ANSI转义码而是根据提示的实际显示长度来确定PS1字符串的长度?

Answers:


21

bash用于\[ \]确定“显示的长度”:这两个转义之间的文本被认为是不可打印的,不计入总长度;其他的一切。

您的变量似乎有一个问题:bright='\[[01m\]'实际上不包含ESC字符,因此[01m将其打印为普通文本,但不计入长度。应该是'\[\e[01m\]'。所有其他变量相同。


有关:

  • 在Bash中,你可以把\$(hg_status)$PS1直接,而不需要单独的PROMPT_COMMAND

1
这提供了部分修复;现在可以正确检测到行长,但是它不能解决第一个换行符覆盖提示的问题。
克里斯·R

1
克里斯·R:我尝试了您的提示,只是在Ubuntu 12.04上'\[['\[\e[bash中的工作代替了所有提示。转义颜色(以及一些其他与提示大小无关的部分)也\[...\]对我有帮助,但我的PS1比您复杂得多(右对齐的文本与提示在同一行,右下角的文本)角)。它解决了早期包装和重叠包装的问题。
TWiStErRob
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.