Why zsh?

People often ask me why I switched to zsh. Back when I had first switched, I was hesitant to answer because I was still finding my way around. Now that I’ve been using it, I’ve managed to distill down a few things zsh does well that sets it apart as my shell of choice.

Syntax Highlighting

In zsh, there’s a plugin that syntax highlights the current command line as you type. It’s incredibly useful to receive instant feedback about whether a command you’re typing is valid. Turns running commands at the command line into nearly the same experience as typing code into your favorite text editor.

The screenshot above features some of the syntax elements it highlights by default:

It also highlights strings, globs, and environment variables (if they’re typed within strings).

There’s probably no technical limitation for why this couldn’t be done in bash, but as of yet no one has done it.

Better Tab Completion

In zsh when you tab complete, the matches are listed below the current line, whereas in bash they’re listed above it. For an example, check out the screenshot. I perform the same keystrokes in bash and zsh:

$ cd D<TAB>

In bash, pressing TAB prints out the completions followed by a new line. In zsh, they’re simply listed conveniently below the current line. If I continued to complete many things in that line or ran the command, zsh would overwrite the old completions, but bash would keep on printing additional lines, taking up precious screen space.

Better Completion Support

When I used bash, I managed to have pretty wide support for tab completion in programs. I’m talking much more than just completing filenames. As such, I was pretty skeptical that there’d be much more that zsh could offer.

While zsh’s edge wasn’t immediately apparent in this aspect, I’d like to declare it a winner now. I had to fight pretty hard to get my bash completions where they were. By comparison, zsh comes with so many more completions built in, and if you decide to use oh-my-zsh (a collection of zsh plugins) on top of zsh, adding new functionality is one line away.

I now have things like environment variable completion, tmux completion, deep git command completion, and much more.

Great, how do I start?

The first step is to change your shell to zsh: chsh -s $(which zsh). Once you’ve done that, you’ll need a .zshrc and .zshenv. If you’re looking for a reference, you can see my misc.zsh file in my dotfiles repo on GitHub, a file which eventually gets sourced in my .zshrc. It contains most of everything that you need to get started using zsh on OS X. Keep in mind that it’s somewhat opinionated (it heavily favors vim keybindings and uses oh-my-zsh among other things). You might also want to check out my Noteworthy Dotfile Hacks post, where I talked about what I think are the most notable features I have in my dotfiles.