Sat 19 May 2012

Protip: Notes in your zsh prompt

I tend to follow good practices. For example, commit certain things in a particular git branch, that should be re-based of another branch that tracks the upstream. However, sometimes I just forget that, especially after not working on that particular code base for a long time, and do a commit in a wrong branch. Git is forgiving, but I wanted more, I wanted to avoid making that mistake in the first place.

So I came up with this nice idea of having notes for different projects, where I would keep track of what need/should be done. Then, when I work on a specific project, by consulting these notes, I would avoid making mistakes. Just to make sure that everything will work, I wanted to have a reminder that these notes exist.

The implementation was straightforward, for several reasons:

The strategy I came up with was to have a special file in the project directory, imaginatively called .note. Then, the code for printing my shell-prompt-on-steroids would also print the content of the .note file. And that is as simple as this excerpt:

# Printing notes in the prompt https://github.com/knl/dotzsh/blob/master/themes/knl2.zsh-theme

function prompt_knl_precmd () {
    local -a lines infoline promptline noteline
    local filler i_width p_width
    local -r NOTE_FILENAME=.note

...

        # assemble the note line
        # The note line is one or more lines, displayed before the main line. It
        # behaves as a reminder. It is only displayed if $NOTE_FILENAME exists in
        # the current directory.
        # The nodeline setup comes after the main line, because I want to align
        # note: text with the promptchar.
        noteline=""
        if [ -e $NOTE_FILENAME ]; then
                local note_readline
                note_readline=`cat $NOTE_FILENAME`

                # alignment calculation
                noteline=( "${(l.$(( $p_width - 5 - 4)).. .)}" )

                noteline+=( "${gray}note " )
                noteline+=( "%# " )
                noteline+=( "${note_readline}${reset}" )
        fi

        ### Now, assemble all prompt lines
    lines+=( "  " )
    lines+=( ${(j::)infoline} )
    lines+=( ${(j::)noteline} )
    lines+=( ${(j::)promptline} )

    ### Finally, set the prompt
    PROMPT=${(F)lines}
}

And it looks like this, for this blog:

If you want to have a closer look, please consult my zsh prompt theme, or have a look at my fork of oh-my-zsh.