Supercharge Your Productivity With iTerm2 & zsh

Jordan Cutler
Dolomite
Published in
11 min readDec 19, 2018

Are you a Mac developer using Terminal and Bash incredibly happy that you don’t have to use Git Bash/Cmd Prompt on Windows?

What If I told you there’s something even better than Terminal and Bash so you can make fun of your Windows user friends even more?

Well, there is, and that’s what we’re going to talk about today — specifically, iTerm2, zsh, and oh-my-zsh

Disclaimer: I actually have no idea how easy it is to make this same configuration setup I’m going to talk about on Windows. I’ll look into making a guide for Windows in the future but for now this is just for Mac users.

Problem

While Bash satisfies many basic needs, it fails to have helpful integrations like autocomplete based on history, syntax highlighting, git branch/status showing by default, nice colored theming/fonts.

By following this guide, you will have all of these things and more. Your terminal will look something like this by the end (and have the ability to use the same shortcuts).

Terminal after tutorial

Vocab

Before getting into the configuration, you should know these terms so you aren’t just “cargo-culting” the tutorial and you have an idea of what is actually going on, and can also help your developer friends!

  1. Terminal: The program built into MacOS which allows you to run shell commands.
  2. Bash: The specific type of shell Terminal uses by default.
  3. iTerm: A program similar to Terminal but comes with many more features and configuration options.
  4. Zsh: Another type of shell, short for Z-Shell. The main reason for using zsh is its seamless integration with the plugin manager, “oh-my-zsh.”
  5. Oh-my-zsh: A plugin manager built on top of Zsh which allows for easy integrations into the zsh shell like the ones mentioned earlier in the article.

So essentially…

iTerm is a replacement for Terminal

Zsh is a replacement for Bash.

Oh-my-zsh is a nice thing to use on top of zsh to add a lot of cool features.

Installations

For this tutorial, I’ll be using Homebrew (a package manager for installing other software easily from the command line) for appropriate installations.

Installing Homebrew

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

IMPORTANT NOTE: In general, for any Homebrew installation, be sure to read any messages Homebrew gives you after installing. If there are any errors, Homebrew will typically tell you the exact command to type to fix the error. Homebrew will also tell you some last step of the installation too like adding a line of code to a settings file, so don’t skip that!

Installing iTerm2

brew cask install iterm2

This will add the iTerm application to your ~/Applications folder

Feel free to install the zip from the website if HomeBrew gives you any issues.

Once you have iTerm installed, open it and run all future commands in there.

Installing Zsh

brew install zsh

Installing Oh-My-Zsh

Make sure you have curl installed for this. If you don’t, you can run brew install curl. You can check if you have it installed by running curl --help in iTerm and seeing if it’s recognized.

sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

This adds a ~/.oh-my-zsh directory with many default themes and plugins which we will edit later.

Installing Fonts

We will use these fonts to style up the iTerm later.

git clone https://github.com/powerline/fonts.git
cd fonts
./install.sh
# at this point you can delete the fonts folder if you want

This will add many fonts to choose from into iTerm.

Restoring Your Bash Settings

It’s likely you had your bash settings stored in a ~/.bash_profile file and you still want some of those settings.

Your new settings are stored in ~/.zshrc. Feel free to copy them over to the bottom of the ~/.zshrc file.

Note: If you did have some sort of git branch display function you’ll want to remove that now as it won’t be necessary since the oh-my-zsh theme will provide that for you.

For those who haven’t heard of “bash settings” or bash_profile; essentially, the two aforementioned files are run as the shell is loaded, so any aliases, environment variables, or callable shell functions are loaded by that file for your terminal session. It is for this reason that after changing ~/.zshrc or updating some sort of terminal/shell configuration, you should restart your terminal to ensure the file gets re-ran and the changes take effect.

An example file like this might look something like this:

export JAVA_HOME=$(/usr/libexec/java_home)
export PATH=$PATH:/usr
export PATH=$PATH:/usr/bin
export PATH=$PATH:/usr/local/bin/
alias gs='git status'
alias dol='cd ~/dolomite/backend'

The exports are for environment variables. The PATH declarations are me appending different files to my PATH, which is the list of locations your terminal application will look after executing a command.

IMPORTANT: I would suggest adding the 3 lines that update your PATH since those may have been in your PATH by default with Bash whereas zsh might not provide those by default.

Finally, the aliases are for declaring helpful shortcuts to speed up development! The nice thing about our setup is soon we will have plugins which automatically add aliases for us.

Changing iTerm to Use Zsh

It’s likely that iTerm is using the default shell, Bash. We want to change that to Zsh so we can get all the fancy features!

Open iTerm Preferences, and in the “Command” textbox, put /usr/local/bin/zsh --login. That is where Homebrew should have installed zsh. The--login part is to help with permissions in rare cases when your shell isn’t treated as a “login shell.” Don’t worry about it too much. It was handled for you before when using bash with Terminal.

Also, you probably want to select “Reuse previous session’s directory” so new tabs open in the same directory you were in.

One other note: You probably want to go to the “Appearance” tab and check “Stretch tabs to fill bar,” it seems more natural and it’s likely what the setting was in Terminal.

Strech tabs to fill bar

Installing External Plugins

Installing Zsh Syntax Highlighting

Zsh syntax highlighting adds super cool colors to shell commands:

colooooorssss
syntax highlighting
brew install zsh-syntax-highlighting

As the Homebrew message states after installation, you will need to add this to the end of the~/.zshrc file.

source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Friendly reminder to restart your terminal window to see the changes take effect :)

Theming

You’ve done a great job so far. We made it to the most important part, making you look like the 1337 h4x0r you know you are.

There are two aspects to the theming here.

First, there is the overall color scheme aspect.

Second, there is the theme which is applied to the shell prompt.

Let’s get the color scheme down first.

Color Scheme/Font

To get a massive amount of different color schemes, let’s use the following repo of iTerm color schemes.

git clone https://github.com/mbadolato/iTerm2-Color-Schemes.git

Go to iTerm Preferences > Profiles > Colors > Import > Color Presets

Color Presets Clicking
Importing iTerm themes

Head to the iTerm2-Color-Schemes/schemes folder from the directory you cloned, then CMD+A to copy all the themes, then hit Enter. It should take a few moments to import all of them.

You can see a preview of each of the themes here

Funny enough, the one I’m using is not on that massive list. To get the one I’m using (material-design-colors), run the following commands, then import that file in the same way you just imported the others.

cd ~/Downloads
curl -O https://raw.githubusercontent.com/MartinSeeler/iterm2-material-design/master/material-design-colors.itermcolors

You should now be able to select the material-design-colors theme from the list of presets. Go head!

To get the text settings… follow this screenshot (the fonts should be there from the prior “Installing Fonts” step:

Updating font

I chose Meslo LG M For Powerline 13pt font as well as the “vertical bar” in the “Text” tab.

Also, you will probably want to uncheck “Draw bold text in bold font” to have a more consistent text experience with other programs outputting text.

Zsh Theme / Git Branch Prompt

While we just configured the color scheme to the terminal, we now need to configure what is displayed at the prompt. For me, that is the current directory followed by git branch information.

Oh-My-Zsh comes with many default zsh themes, you are likely using the “robbyrussell” default theme. It should show you in the ~/.zshrc file near the top at the line ZSH_THEME=“robbyrussell” line. These default themes are stored in your ~/.oh-my-zsh/themes file. Feel free to runls ~/.oh-my-zsh/themes to check them out.

I personally had small gripes with all of the defaults, so I modified the “cloud” default to fit my purpose. A lot of the time the defaults would either not show the entire working directory, or they would also show the user/machine, which is unimportant in my opinion (at least in my lack of devopsing experience).

To get what I have… put the following file from the gist I created in your ~/.oh-my-zsh/custom/themes/ folder:

The resulting path should be

~/.oh-my-zsh/custom/themes/cloud_custom.zsh-theme

Now your ~/.zshrc file can find the theme.

Change the theme line in your ~/.zshrc to…

ZSH_THEME="cloud_custom"

Restart your terminal and you should have the same theme now. Head to a git folder you have to confirm.

Here’s a list of all the defaults with screenshots if you’re interested:

https://github.com/robbyrussell/oh-my-zsh/wiki/Themes

Plugins To Make Your Dreams Come True

The following is a gist I made which contains a “plugins” array you can copy over to your ~/.zshrc plugins ( ) section to get all of the common useful plugins. They are all commented well, explaining the basic usage if applicable and the GitHub link to further documentation.

Here I’ll briefly touch on some of my favorites of these:

autojump is suuuper awesome. As long as you have gone to a directory before, you can simply type j {partial directory name} and it will go to that directory, rather than having to type out the full path. For example, if I wan’t to go to ~/dolomite/backend, I can type j ba (from anywhere in terminal) and that would be enough for it to figure out I want to go to ~/dolomite/backend.

Another cool plugin is osx, which allows you to interact with finder through terminal.

Finally, zsh-autosuggestions will add “new Gmail-like” autocomplete features based on past commands. For example:

Autocomplete zsh

You may not be able to tell, but I only started typing cd and it allowed me to optionally finish by pressing AKA “up-arrow”. It works in a very similar way to reverse searching with “ctrl-r” for those familiar but is a first-class citizen instead.

The other plugins are mostly alias plugins, like git, which I highly recommend using as those commands add up in time spent.

Here’s a short list of conversions:

git status => gst
git checkout => gco
git add => ga
git fetch => gf
git log --oneline --decorate --color => glo
git push => gp

Note: I also added a line to my ~/.zshrc to give myself an additional git status alias of gs since that’s what I was used to before doing this setup, plus it’s one character shorter :). To do the same, add this line to ~/.zshrc.

alias gs='git status'

How Can I Remember The Aliases?

Saving the best for last, there is an external plugin called alias-tips which reads the command you used, cross-references it with all the available aliases, and tells you if you could have used an alias instead.

To install the external plugin, we can download an external plugin which manages/allows for easy installation of other external plugins, called antigen.

brew install antigen

Follow the instructions provided about adding

source /usr/local/share/antigen/antigen.zsh

to the end of ~/.zshrc.

Below the line you just added, add the following:

# Bring in external plugins using Antigenantigen bundle djui/alias-tips# Apply antigen transformations
# All other antigen calls should be preceded by the "antigen apply" call
antigen apply

Antigen works by you telling it all the external plugins it should grab, then ending with an “apply” call which integrates them into the shell session.

Now you should see alias tips when you could have used an alias, as shown in the initial picture.

alias tip

alias-tips told me to use gcm instead of gco master.

Honorable Mention Aside

Another great program I suggest installing is “the silver searcher,” also known as ag.

brew install the_silver_searcher

If you’ve used ack before it’s like that but faster. It allows you to search files for text extremely quickly. Here’s a little sample usage of me searching for RichFutureSeq, Dolomite’s internal library for extension methods on the type Future[Seq[T]] in Scala.

Silver searcher usage

My mouse went missing in this image, but another thing that’s really cool about iTerm is if I hold CMD and hover over that file extension, I can click it and it will open that file in my text editor.

Here’s the man (manual) page for ag, showing it’s simple usage of typing a pattern and a path to search. Note the coloration is provided by colored-man-pages plugin which was on the list of plugins I provided.

Other Plugin Notes

All of the default plugins which can simply be added to the “plugins” array are here:

https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins

Additionally, this repo is a great list of plugins with descriptions and links to their GitHub (with these plugins you may or may not be able to simply add to plugins array. Some are external, some aren’t):

I’ve only got through a few of these plugins so far. Though I’ll probably add more, be careful, because the more you add the more it slows down start-up time of the terminal.

Thanks for making it this far and I hope you found this useful! If you would like to see more articles like this, feel free to message me or comment below and I’ll gladly do more. Don’t forget to show clap support :)

Dolomite Social Media

My Social Media

--

--

Jordan Cutler
Dolomite

Author of High Growth Engineer (45k+ readers) & Senior Software Engineer