Search code examples
bashprompt

Added git branch to bash prompt, now it can't find the start of the command


I added the git branch to my bash command line according to the method in https://stackoverflow.com/a/35218509/19776334.

My .bashrc file contains the following lines:

parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1] /'
}

PS1="\[${COLOR_LIGHT_RED}\]\d \t \[${COLOR_GREEN}\] \[\$(parse_git_branch)\]\[${COLOR_LIGHT_PURPLE}\]\w \[${COLOR_YELLOW}\]>> \[${COLOR_NC}\]"

It looks the way I want, but sometimes I get strange behavior. If I scroll up to a long command I had previously entered and press Home, the cursor goes to the middle of the branch name. If I then try typing, some of the command disappears.

I changed parse_git_branch to

    parse_git_branch() {
    echo
    }

Then there was no problem with the column. I'm sure this isn't the right way to write in bash. I just wanted to keep the function but return an empty string.


Solution

  • The behavior you're seeing is what you'd get if readline mis-counts the column positions. The \[ ... \] sequences in PS1 tell readline that the characters output here are "invisible" (take up no screen columns), so you only want to use them when the characters are actually invisible.

    Let's look at your PS1 setting, breaking it into parts:

    PS1="\[${COLOR_LIGHT_RED}\]
    

    This is good and right, because (presumably) the ${COLOR_LIGHT_RED} variable expands to a color-changing sequence that takes no display columns.

    \d \t \[${COLOR_GREEN}\] 
    

    This, too, seems all good-and-right: \d and \t give the date and time, and do take up columns. The spaces, including the one after the switch to green color, do as well.

    \[\$(parse_git_branch)\]
    

    Uh oh! The parsed git branch is printed, and takes up columns, when there's a parsed branch. This should be counted.

    \[${COLOR_LIGHT_PURPLE}\]\w \[${COLOR_YELLOW}\]>> \[${COLOR_NC}\]"
    

    The rest looks fine.