title: Oh My Zsh!
tags: terminal, zsh, scripting, console, productivity, tools, cli, command-line, bash
date: 2015-11-28 15:18:38+00:00

## Introduction

Hardly any developer can go about his career without interacting with the terminal on daily basis. Many tools continue to be developed as command line apps, like [fastlane](http://fastlane.tools), [Jekyll](https://jekyllrb.com), and many more ... With all that being said, we need to make terminal more usable!

Recently, I've been ssh-ing into an Ubuntu server that defaults to bash, and I quickly realized how my terminal life has been completely turned around thanks to [zsh](http://zsh.org). Here are a few examples of why it is just pure awesomeness.

Before I begin, let me just say that I have immediately installed [Oh My ZSH](http://ohmyz.sh/) right after installing zsh itself, so I am not sure which features are specific to zsh and which are added by the plug-in.

## Z Shell

When mentioning the features, I guess I'll sort them in terms of the most important to me, down to the most "meh". It's purely subjective, but here we go:

### Timelapse

I can't get enough of this feature. You simply type a command, then hit the up arrow key, and BAM! You are cycling through your history __of that specific command__:

```bash
% ssh-add ↑
% ssh-add ~/.ssh/github-terminal
```

This feature saved me countless (accumulated) hours. From running `py.test`, adding ssh keys, all the way to simply removing Xcode's derived data folder:

```bash
% rm ↑
% rm -Rf /Users/mazyod/Library/Developer/Xcode/DerivedData
```

It is by far my best feature, but the rest of the features are pretty kickass as well.

### Cycling

If you are a lazy typer like me, then you'd feel for me when I say that nothing is more annoying than bash continuously blocking [Tab] completion because many completions exist!

```bash
$ ss⇥
SSH_AUTH_SOCK  ssh-keygen   
ssh            ssh-keyscan  
ssh-add        sshd         
ssh-agent      sso_util
$ ssh-⇥
ssh-add      ssh-keygen
ssh-agent    ssh-keyscan
$ ssh-a⇥
ssh-add    ssh-agent
```

Annoying!!! How does zsh solve that? Well, if you hit __double tab__, it shows a selection highlight, so you can cycle through the options and choose the command you like!

![image](/images/zsh-cycling.png)

This is just so convenient...

### Auto-Correction

Once you start typing a command then hit Tab, it can correct your typo automatically, and does so in many ways!

#### CUSTOM AUTO COMPLETION

With the right plug-ins from oh my zsh, you can have custom auto completion for your favorite commands! Let's see `git` for example:

```bash
% git⇥
add       -- add file contents to the index
bisect    -- find by binary search the change that introduced a bug
branch    -- list, create, or delete branches
checkout  -- checkout a branch or paths to the working tree
clone     -- clone a repository into a new directory
commit    -- record changes to the repository
diff      -- show changes between commits, commit and working tree, etc
fetch     -- download objects and refs from another repository
grep      -- print lines matching a pattern
init      -- create an empty Git repository or reinitialize an existing one
log       -- show commit logs
merge     -- join two or more development histories together
mv        -- move or rename a file, a directory, or a symlink
pull      -- fetch from and merge with another repository or a local branch
push      -- update remote refs along with associated objects
rebase    -- forward-port local commits to the updated upstream head
reset     -- reset current HEAD to the specified state
rm        -- remove files from the working tree and from the index
show      -- show various types of objects
status    -- show the working tree status
tag       -- create, list, delete or verify a tag object signed with GPG
```

#### WRONG COMMAND

```bash
% xcodeguild
zsh: correct 'xcodeguild' to 'xcodebuild' [nyae]?
```

Not only does it correct it for you, but also allows you to hit `e` and edit the command, just in case it didn't get it right.

#### MIND READER

zsh ships with a mind reader, really! Look:

```bash
% ls
blog          untiy3d-game  upcoming-book
% cd game⇥
% cd untiy3d-game/
```

#### I DoNt cArE

As a final note, zsh doesn't torture you for not getting the CAPS right. It will happily accept wrong caps for files, and correct that for you.

```bash
% cd doCuMent⇥
% cd Documents/
```

### ZMV

I am not sure where this command comes from, but it is just super for renaming files. All you have to do is autoload it, and then use it. For example, let's say we have a bunch of png images we want to append `@2x` to the end, before the extension:

```bash
% autoload -U zmv
% zmv '(*).png' '$1@2x.png'
```

This is not all ... If the rename will mess up your files by overwriting each other, it will detect that and abort the whole operation, leaving your files intact! In case you didn't understand, let's see the following example.

Here, I inaptly tried to rename all the images in an Xcode catalog tree to "oops.png" in the root directory. Normally, this command would mean I lose all the images, and only get a single image "oops.png", corresponding the the last image the command runs on. Not zmv. It gave me a readable error, and aborted the operation. I checked git, nothing changed at all!

```bash
(master)⚡ % zmv '(*)/(*).png' 'oops.png'
zmv: error(s) in substitution:
button.imageset/button@2x.png and button.imageset/button.png both map to oops.png
```

### Themes

YES! Zsh allows you to install custom themes shared by other awesome people, and the choices are just too good. So many different themes, it's hard not to find what you are aiming for.

My choice was tricky, yet I still found the exact theme I wanted. I need something that shows the cwd on the right, the colors to be according to [SMYCK color scheme](http://color.smyck.org/), displays the active git branch, and nothing else. It must be minimal .. and I found it, the wezm theme:

```bash
ZSH_THEME="wezm" # norm also good
```

![image](/images/zsh-theme.png)

### Misc

Here is a dump of more features that collectively make terminal a hell lot more usable.

#### NUKE CONFIRMATION

I am not worried about typing `sudo rm -Rf *` anymore.

```bash
% rm -Rf *
zsh: sure you want to delete all the files in /Users/mazyod [yn]?
```
