1

The Goal

I'm trying to colorize my bash prompt on Mac OS X with the git branch (where available).

What I've Tried

With my limited bash knowledge, I pieced together the following code from Google searches and other questions:

function parse_git_branch() {
        branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)

        if [[ -z "$branch" ]]; then
                return
        fi

        if [[ -z "$(git status -s 2>/dev/null)" ]]; then
                color=$'\e[1;32m'
        else
                color=$'\e[1;31m'
        fi

        echo "\[$color\] (${branch}) "
}

PS1="\h:\W \u\$(parse_git_branch)\[\e[0m\]\$ "

The Problem

While the coloration works, the prompt contains some of the escape sequences from parse_git_branch.

leonidas:AYI jason\[\] (master) $

In addition, things like command history (up) and recursive search (ctrl+r) yield extra characters.

leonidas:AYI jason\[\] (master) $h)`re': git status

The Questions

  1. How can I fix the escaping with proper visible and non-visible characters.
  2. Should I use tput instead of these color codes for wider support?
5
  • 3
    (1) switch to zsh, (2) get oh-my-zsh, (3) choose a theme, (4) never look back! Commented Dec 30, 2013 at 2:07
  • 2
    @Oli Charlesworth, thanks for the suggestion. But I'd like to solve the current problem. Commented Dec 30, 2013 at 2:10
  • @Kevin, Could you provide more information - where, why? Commented Dec 30, 2013 at 16:36
  • When you set PS1="...$(parse_git_branch)...", it is evaluated precisely once, while sourcing the file. You need PS1='...' to have it evaluated every time. Commented Dec 30, 2013 at 16:39
  • @Kevin, that's not the problem I am having. It is evaluated every time. Commented Dec 30, 2013 at 16:43

2 Answers 2

3

Why go to all this trouble. Just create a .bash_profile Mine is:-

export PS1="\[\033[0;30;33m\]\w\[\e[0m\]$ "

You should set .bashrc to reference this

[ -r ~/.bash_profile ] && source ~/.bash_profile
Sign up to request clarification or add additional context in comments.

1 Comment

See my update, I'm trying to include the git branch (if available).
2

The problem is that \[ \] is not respected in expanded data.

To get around it, you can set PS1 to a post-expansion version of itself in PROMPT_COMMAND, whose contents is evaluated before every prompt:

PROMPT_COMMAND='PS1="\h:\W \u$(parse_git_branch)\[\e[0m\]\\\$ "'

Since the \[ \] are now part of the literal value of PS1, and not created by prompt expansion, they're correctly interpretted.

2 Comments

yup. Simpler example: ps1() { echo '\h:\W$ '; }; PS1='$(ps1)'; Your prompt will be literally \h:\W$ .
While I will try this, it feels hackish to me. There must be a way to fix what I have.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.