bashshpromptgit-bash

Set PS1 with subcommand that prints colors


When putting ANSI color codes in PS1, they need to be surrounded with \[\] or else the prompt can get confused about where the editable part of the line starts. However, when a subcommand ($()) prints colors, the \[\] escapes are always being written literally to the prompt...and with long enough commands in my history, the prompt gets confused.

Here's an example:

ps1test() {
    ps1sub() {
        printf '\[\033[32m\]Hello!\[\033[0m\]'
    }
    PS1='$(ps1sub) \$ '
}

Expected:

$ ps1test
Hello! $

Actual (bash installed by Git for Windows):

$ ps1test
\[\]Hello!\[\] $

How can I get my shell to interpret the \[\] escapes from a subcommand?


Solution

  • Only \[s in the literal string are interpreted. \[s resulting from embedded expansions are not.

    The easiest way to get around it is to have PROMPT_COMMAND set a PS1 to a new literal value each time:

    updateps1() {
        ps1sub() {
            printf '\[\033[32m\]Hello $RANDOM!\[\033[0m\]'
        }
        PS1="$(ps1sub) \\\$ "
    }
    
    PROMPT_COMMAND='updateps1'