In this article I’m going to show you how you can vastly improve your terminal. We’ll start with the default terminal shown in the first screenshot and enhance it so that it looks something like the terminal shown in the second screenshot:
We’ll accomplish that by switching the shell from the default shell Bash to the much more powerful and customizable Z shell. To simplify the configuration process we’re going to add the configuration framework Oh-My-Zsh on top of the Z shell. Then, we will replace Apple’s stock terminal emulator Terminal.app with the more powerful iTerm2 and change the terminal’s appearance with a nice color scheme.
Installing the Z Shell
Like many other system programs, the Z shell is already installed on your Mac by default. You can verify that by entering which zsh
into your Terminal. As with most other pre-installed software, however, this system-provided version of zsh
is pretty outdated and shouldn’t be used. We’re going to install our own version of zsh
instead, using a tool called Homebrew. That version will be easier to maintain and works much better with the rest of your software. Thus you should know how to use Homebrew before you continue reading. In case you don’t know what Homebrew is, I covered it in-depth in a previous blog post. Go read that post first and come back here afterward.
Once you’ve installed Homebrew, you can install the most recent version of zsh
via this command:
brew install zsh
Next, we’re going to install Oh-My-Zsh, a great framework for zsh
that really simplifies the configuration and also includes a couple of cool themes for the prompt.
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
Before you can actually start using this newly installed version of zsh
, you first need to add it to the list of known shells, which is located at /etc/shells
. Sounds complicated, but is really simple. All you need to do is to run this command:
echo /usr/local/bin/zsh | sudo tee -a /etc/shells
With this command, we’ve only made the new shell available to the system. To actually use it though, we still need to explicitly tell the system so.
chsh -s /usr/local/bin/zsh
Checking the title bar of Terminal.app confirms that you’re now using zsh
instead of bash
. You might have to close the terminal and re-open it for the changes to take effect. So now that we’ve successfully made the switch to zsh
, the next step might seem superfluous at first—we’re going install a current version of bash
, too. The reason is that during the execution of some commands such as brew update
you will see that the job name in the title bar of the terminal window changes from zsh
to bash
. That’s because various processes still use bash
in the background. Just because you aren’t using bash
anymore does not mean that it’s not used anymore at all. Keeping bash
up-to-date, too, thus seems like a good idea. Like zsh
, the pre-installed version of bash
is pretty outdated, so we should install our own version of bash
for the same reasons as above:
brew install bash
While we’re at it anyway, we can add that new version to /etc/shells
, too, just in case you want to go back to bash
some day. Since we don’t run the command for actually changing the shell afterward, adding it to /etc/shells
has no effects at all.
echo /usr/local/bin/bash | sudo tee -a /etc/shells
Installing Plugins
Next, let’s install a few of the plugins that make zsh
so much better than bash
. The first one is for auto suggestions. It tries to complete the missing words to your command before you’ve even started typing them, very much like what a Google search in your web browser does:
brew install zsh-autosuggestions
echo 'source /usr/local/share/zsh-autosuggestions/zsh-autosuggestions.zsh' >> ~/.zshrc
The second plugin is simply called z
. It remembers the paths you cd
into. You then only need to type the first couple of letters of a folder instead of its entire path, for example z proj
instead of cd ~/pretty/long/path/to/some/project-folder
. This is a huge timesaver.
brew install z
echo '. `brew --prefix`/etc/profile.d/z.sh' >> ~/.zshrc
Another cool plugin is for syntax highlighting. It will tell you whether the commands you’re trying to execute are valid commands by coloring them either green or red.
brew install zsh-syntax-highlighting
echo 'source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' >> ~/.zshrc
The fourth plugin we’re going to install makes it easier to run previously executed commands again.
brew install zsh-history-substring-search
echo 'source /usr/local/share/zsh-history-substring-search/zsh-history-substring-search.zsh' >> ~/.zshrc
echo 'bindkey "$terminfo[kcuu1]" history-substring-search-up' >> ~/.zshrc
echo 'bindkey "$terminfo[kcud1]" history-substring-search-down' >> ~/.zshrc
source ~/.zshrc
What this fourth plugin allows you to do is the following: Imagine you installed some program a while ago, but you can’t remember whether you used brew install
, pip install
, conda install
oder npm install
. With this plugin, you can simply type the name of the program into the terminal and press the Up and Down keys to cycle through all commands in your history that match the program name. More generally, you can enter any substring of any previously executed command and the Up and Down keys will find that old command. In case this feature does not work for you, delete the two bindkey
lines from your ~/.zshrc
file and try again after executing these commands:
echo 'bindkey '^[[A' history-substring-search-up' >> ~/.zshrc
echo 'bindkey '^[[B' history-substring-search-down' >> ~/.zshrc
source ~/.zshrc
Notice how, after each plugin we installed, we had to add a line of code to a certain file located at ~/.zshrc
. This ~/.zshrc
file contains all the run commands for zsh
.1 For bash
, there are similar files, e.g., ~/.bashrc
or ~/.bash_profile
. Such files are called dotfiles. If you’re interested in what they are and how they work, you can read more about them here.
What you need to know about dotfiles for now is that a few important things are probably going to break after switching from bash
to zsh
. That is because you’ve most likely set your environment variables (e.g., PATH
, JAVA_HOME
, etc.) in either ~/.bash_profile
, ~/.profile
or ~/.bashrc
. These three files are all meant for bash
and will not be read by zsh
.2 Therefore your system won’t know your PATH
or JAVA_HOME
anymore—it’s just like you never told the system about these variables in the first place. To make things work again, you need to tell zsh
the values of these variables in a language zsh
is able to understand, figuratively speaking. One way to do that is by simply sourcing your respective dotfile from ~/.zshrc
. If you’ve followed my guide, it would be ~/.bash_profile
which you need to source:
echo "[[ -e ~/.bash_profile ]] && emulate sh -c 'source ~/.bash_profile'" >> ~/.zshrc
This command tests whether ~/.bash_profile
exists and if so, emulates the sh
shell in order to source ~/.bash_profile
. The reason for this is that the syntax of zsh
is not completely compatible with sh
and bash
. These incompatibilities could potentially break scripts in ~/.profile
or ~/.bash_profile
if we don’t enter emulation mode before reading these files when using zsh
. Another way, of course, would be to cut & paste your code from ~/.bash_profile
into ~/.zshrc
rather than sourcing it.
To understand this important topic of dotfiles better, you should really read the post mentioned above. Otherwise things might just not work anymore and you’d have absolutely no idea why.
Customizing the Appearance of the Terminal
If you’re like me, you really don’t care about that very first line in the terminal which tells you the time of your last login. You can suppress it like so:
touch ~/.hushlogin
Next, you’ll want to alter the prompt of your terminal.
Update: I’ve since switched to the starship prompt. You can install it like so:
brew install starship
echo 'source "$ZSH/oh-my-zsh.sh"' >> ~/.zshrc
echo 'eval "$(starship init zsh)"' >> ~/.zshrc
You can skip the following lines and continue with the part where we install iTerm2.
First, visit the themes website and check out which themes you like. Personally, I like nebirhos
the most. After you’ve found a favorite, open ~/.zshrc
in a text editor, for example with this command:
open -e ~/.zshrc
In this file, search for the line ZSH_THEME="robbyrussell"
and replace robbyrussell
with the name of the theme you want to try, e.g., nebirhos
. For the change to take effect, you either need to open a new terminal window or enter source ~/.zshrc
into the terminal.
I made some additional tweaks to nebirhos
and adjusted it to my liking, since I don’t need to see, e.g., the Ruby version next to the arrow all the time. To modify a theme, you can either open its folder with
open ~/.oh-my-zsh/themes/
and search for the theme in the Finder, or alternatively open the theme directly if you know its name:
open -e ~/.oh-my-zsh/themes/nebirhos.zsh-theme
Beware that these “themes”—despite their name—modify only the appearance of the prompt, i.e., the fat arrow at the beginning of each line or the name of the current branch but not the background color of the terminal etc. A color scheme is what you’re looking for if you want to change the background color (more on that in the next section).
As you can see, you can use zsh
with Terminal.app too; none of the changes so far had to do anything with iTerm. But I recommend using it instead of Apple’s Terminal.app, nevertheless, since its far more customizable. You can install it with this command:
brew install iterm2
Color Schemes
You can find many pretty color schemes for iTerm here. One of my favorites is Whimsy. Other popular color schemes include Gruvbox, Dracula, Nord, and Everforest which you’d have to download from here. You can either download the whole folder as a zip-file or take the shortcut and download the mentioned scheme directly via curl
to your Downloads folder.
cd ~/Downloads; curl -O https://raw.githubusercontent.com/mbadolato/iTerm2-Color-Schemes/master/schemes/Whimsy.itermcolors
Then go to Profile > Colors
in iTerm, where you can import the color schemes.
General Settings
I dislike the native full screen when you press ⌘
+Enter
, so I deactivated it under General > Window
. Under Profile > Terminal
you should enable “Silence Bell” to disable the annoying sound effect.
Fonts
Change the font to a prettier one by first installing, for example, IBM Plex Mono as follows and then setting the font and font size under Profile > Text
.
brew tap homebrew/cask-fonts
brew install font-ibm-plex
Other nice fonts are:
brew install font-fira-code
brew install font-hack
brew install font-source-code-pro
brew install font-jetbrains-mono
Nerd Fonts
I use Vim as my text editor and Vim can display pretty icons in my terminal to call my attention to potential mistakes. The above-mentioned starship prompt also displays pretty icons. To display such icons, the font must include icons to begin with, which fonts typically don’t. Therefore, some people went ahead and added these pretty icons to their favorite fonts. We say they “patched” the font. The resulting fonts that now include icons are called Nerd fonts. Unfortunately, there’s no patched variant of IBM Plex, so even though it is a nice font, I cannot use it if I want the pretty icons in the starship prompt and Vim. The font Hack on the other hand is one of the fonts that has been patched, so personally I use the Hack Nerd font:
brew install font-hack-nerd-font
I’ve set it to 13pt
.
However, these fonts that include icons require more disk space than the regular fonts, so if you don’t use Vim or the above-mentioned starship prompt, there’s absolutely no need or benefit in using Nerd fonts. They’ll just take up more disk space. In that case, it’s perfectly fine to use the non-Nerd fonts (for example, brew install font-hack
) if you don’t yet understand for what exactly you’d need a Nerd font.
Keyboard Shortcuts
Add two new key mappings under Profiles > Keys
for quicker navigation between words by click the +
button you will find there.
Word Jump to the Left
To create a keyboard shortcut that will move the cursor to the left by one word, click in the field named “Keyboard Shortcut” and press the ⌥
key and the left arrow key simultaneously, so that the combination ⌥←
appears. Select Send Escape Sequence as action and enter the letter b
in the Esc+ field where it says “characters to send”. Confirm with “OK”.
So to recap, here’s what you should do:
Keyboard Shortcut: ⌥←
Action: Send Escape Sequence
Esc+: b
Word Jump to the Right
Same procedure as above, except that you press the right arrow key and enter the letter f
instead of left arrow and b
.
Keyboard Shortcut: ⌥→
Action: Send Escape Sequence
Esc+: f
Final Words
You might want to explore the other settings to adjust iTerm even further to your needs. For example, you might want to assign a system-wide hotkey to open the terminal from anywhere. Since this comes down to personal preference, from here on I’ll leave you to figure out for yourself which settings you find useful.
If this article was helpful, why don’t you let me know and leave a comment down below? This keeps me motivated to write even more guides for you 😊 Also, I’d really like to see what you’re doing out of your terminal. Hit me up on Twitter if you want to share a screenshot of your masterpiece or in case you found a helpful little plugin I didn’t mention.