ZSH config from scratch

04 Nov 2012 in Tech

I've been using ZSH for just over a year now, thanks to oh-my-zsh, but I realised that I probably wasn't using it to it's full potential. It's the same kind of thing as when I tried to use Vim, I just forked someone else's settings and didn't realise just what was going on.

A few weeks ago, I decided to start from scratch and see what I could come up with. I'm already back to what I used, and I understand how it all works too!

Autocomplete

The first important line is this one:

bash
autoload -Uz compinit && compinit

Without it, any completion files we add won't be used. Completion in ZSH is awesome, so I'd definitely recommend using this one. Here's an example of completion when typing git<tab><tab>.

bash
$ git<tab><tab>
add -- add paths to the index
am -- apply patches from a mailbox (cooler than applymbox)
annex -- manage files without tracking content
annotate -- annotate file lines with commit info
apply -- apply patch on a git index file and a work tree
applymbox -- apply patches from a mailbox

Setting up your prompt

One of the main reasons I started using oh-my-zsh was for the prompts it provided. I managed to build a prompt I was happy with, using the following functions:

bash
autoload -U colors && colors
function prompt_char {
git branch >/dev/null 2>/dev/null && echo '±' && return
hg root >/dev/null 2>/dev/null && echo '' && return
echo '$'
}
function git_branch {
BRANCH="$(git symbolic-ref HEAD 2>/dev/null | cut -d'/' -f3)"
if ! test -z $BRANCH; then
COL="%{$fg[green]%}" # Everything's fine
[[ $(git log origin/master..HEAD 2> /dev/null ) != "" ]] && COL="%{$fg[blue]%}" # We have changes to push
[[ $(git status --porcelain 2> /dev/null) != "" ]] && COL="%{$fg[red]%}" # We have uncommited changes
echo "$COL$BRANCH"
fi
}
function precmd() {
NAME=""
if [[ $(whoami) != "michael" ]]; then; NAME="%n%{$reset_color%}@"; fi;
PROMPT="%{$fg[red]%}$NAME%{$fg[green]%}%m %{$fg[yellow]%}%~ %{$reset_color%}% $(prompt_char) "
RPROMPT="$(git_branch)%{$reset_color%}%"
}

The $fg array is provided by the line:

bash
autoload -Uz compinit && compinit

What this does, is load up some colour code escape sequences and gives them nicer names for you to use.

Vim mode

Once you start using vim, you get frustrated when your normal movement commands won't work. The following options enable vim mode, and remap jj to <esc>.

bash
bindkey -v
bindkey -M viins 'jj' vi-cmd-mode

ZSH Syntax Highlighting

This one's awesome. It highlights what you're tying in real time. If the program doesn't exist, the text is red - if it does, it's green. It highlights matching brackets, text inside quotes, loads of stuff.

To use it, clone zsh-syntax-highlighting from GitHub and add the following commands to your .zshrc. They'll enable the common highlighters, and add a warning highlight when you try and use rm -rf.

bash
source ./zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern cursor)
ZSH_HIGHLIGHT_PATTERNS+=('rm -rf *' 'fg=white,bold,bg=red')

And more?

That's about as far as I've come with my .zshrc for now. It does everything I knew I wanted it to do (and even some stuff I didn't know I wanted until it did it). If I find anything else that's cool, I'll be sure to blog about it.