Wednesday, October 13, 2010

Ritalin for your $PS1

In my last post I shared my colorful but otherwise inert bash prompt. Pedro Melo extended it to integrate __git_ps1 with extra coloring using git status.

Unfortunately this can take a long while on large source trees (git status needs to scan the directory structure), and while smart bash prompts are handy, it can be frustrating if every prompt incurs a delay.

Of course this is annoying for any over zealous $PROMPT_COMMAND, not just git status based ones.

My version of his version has a small trick to add simple but effective throttling:

_update_prompt () {
    if [ -z "$_dumb_prompt" ]; then

        # if $_dumb_prompt isn't set, do something potentially expensive, e.g.:
        git status --porcelain | perl -ne 'exit(1) if /^ /; exit(2) if /^[?]/'

        case "$?" in
             # handle all the normal cases
             ...
             # but also add a case for exit due to SIGINT
             "130" ) _dumb_prompt=1 ;;
        esac
    else
        # in this case the user asked the prompt to be dumbed down
       ...
    fi
}

# helper commands to explicitly change the setting:

dumb_prompt () {
    _dumb_prompt=1
}

smart_prompt () {
    unset _dumb_prompt
}

If the prompt is taking too long to show up I simply hit ^C and my $PROMPT_COMMAND becomes a quicker dumbed down version for the current session.

2 comments:

Brock said...

Maybe you should add a sigalarm to time it out for you :)

--awwaiid

nothingmuch said...

I actually tried that initially, every combination of ulimit, trap, bash job control, i could think of, before I realized this is much simpler *and* more usable.