Creating the Perfect Terminal Experience on your Mac 

Abhinav Bhardwaj
codealchemist
Published in
12 min readSep 27, 2020
This might be you, after 20 minutes!! 😂

I usually spend a lot of time on terminal and realized that the default terminal shipped with macOS is a bit unproductive and boring to say the least. You can pretty easily notice a big jump in your productivity when you shift to a more powerful terminal.

The setup is based on what I have configured on my MacBook Pro. A similar setup can be recreated on Linux distributions as well.

Let’s see how to configure a powerful and productive terminal experience.

The ingredients for that sleek experience:

PS: I will try to keep it concise (with side-info only poured in on a need-to-know basis.)

Step 1:
Install Hombrew

To check if it is already installed on you system, execute -
brew -v

If an error is throw on screen, Homebrew is not installed yet.

Running this👇 command on you terminal is all you need to do to install Homebrew.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Homebrew should be your go-to package manager on macOS, makes it pretty simple to install/uninstall stuff with just a single command. You wouldn’t want to spend half an hour handling dependencies when Homebrew allows you to wrap up in a jiffy.

Link 👉 https://brew.sh/

Homebrew installation is complete!!

Step 2:
Install iTerm2

- Download iTerm2 using the link provided below.
- Extract the zip file, the app will be extracted in your Downloads folder.
- Move the app to Applications folder.

Your iTerm application is ready for use.

The default Terminal app on macOS leaves much to be desired. iTerm2 on the other hand is beautiful, has nice color and font options, feels almost complete — right out of the box, and at the same time is greatly customizable — tinker with it anyway you want to suit your needs. THERE IS NOTHING MORE TO SAY. Once you start using iTerm2, there is no going back. 😍

Link 👉 https://iterm2.com
Via Homebrew 👉 brew cask install iterm2

This is how I like it!! 🤤

Step 3:
Install Zsh

Open iTerm2 and execute the command:-
brew install zsh.
Let it complete, it may take quite some time :)

Zsh installation is complete!!

Zsh (or Z shell) is an extended version of Bash, although the word “extended” doesn’t do justice to what this shell has to offer. Again, it has a great support for themes, plugins and is ridiculously customizable.

Command 👉 brew install zsh

Step 4:
Install Oh My Zsh

Open iTerm2 and execute the command —

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Oh My Zsh is basically an open-source framework built to let you manage your zsh configuration easily. This is what will allow us to install plugins, themes etc. of our choice.

Oh My Zsh is complete!!

Link 👉 https://ohmyz.sh/

Step 5:
Make Zsh your default shell

During installation of oh-my-zsh, you will be prompted for password which is needed for setting Zsh as your default shell. This might fail under certain circumstances.

Look for confirmation in the last few lines printed on terminal after oh-my-zsh is installed (the photo above).
- In case default shell could not be changed, a statement along the lines of “failure in changing default shell” will appear.
- You should preferably, close the current instance of terminal, open a fresh one and execute echo $SHELL to confirm. Output should be /usr/bin/zsh or /bin/zsh(or something similar). If it is /usr/bin/bash or /bin/bash, that means the operation was unsuccessful.

In that case, you can manually change your default shell to Zsh by —
- Executing chsh -s $(which zsh) on your terminal.
- If the above command does not work, try executing — chsh -s /usr/local/bin/zsh
- Note that this will not work if Zsh is not in your authorized shells list (/etc/shells) or if you don't have permission to use chsh. If that's the case you'll need to use a different procedure. Follow the links below if a similar issues crops up for you. [You may have to do a few Google searches if even these don’t work out for you.]

Step 6 (optional):
There is a chance that username/hostname are not being rendered properly. This is because many themes require Powerline fonts to be rendered properly. I have covered the fix for this in next section.

User info not being rendered properly. Strange ‘?’ looking icon seems to have appeared

TILL THIS POINT WE ARE DONE WITH —
1. Installing Homebrew, the preferred package manager for macOS.
2. Installing iTerm2, a better alternative for default Terminal app.
3. Installing Zsh (aka Z shell).
4. Installing Oh My Zsh, a framework which eases customization.
5. Setting Zsh as our default terminal (so you don’t have to do it manually everytime).

That is pretty much it. You can stop here if you are satisfied with mediocrity :P. But you will have to spend a few more minutes to get that perfect Terminal experience. 😃

What we want to achieve?

  • Bring to life a Terminal which looks as if it came straight out of a movie. Make it more appealing, visually.

We will mainly be dealing with .zshrc file located in home directory. zshrc file is a script that is executed everytime zsh is started. So, any sort of initializations, imports etc. are made in this file and they are automatically reflected in our terminal sessions.

This is what .zshrc file looks like

Step 7:
Configuration and Theme changes for zsh.

— Open iTerm2 and go to Home directory. Execute - cd ~
— Use either vim or nano to open zshrc file. Execute -vi .zshrc
— The file is being shown in read-mode. To edit the file, hit i on your keyboard.

Opening .zshrc file
Hit ‘i’ key on keyboard to start editing the file [Notice — INSERT — has appeared at the bottom]

— Type the following lines in the file:

export ZSH="/Users/<YOUR_USERNAME>/.oh-my-zsh"
export PATH=/usr/local/bin:$PATH
source ~/.bash_profile # Only add this line if .bash_profile exists in you home directory

— There are two pre-installed themes. I personally prefer “agnoster” theme. Change the ZSH_THEME environment variable to:

ZSH_THEME="agnoster"    # replace ZSH_THEME="robbyrussell" with this

— By default, you will be prompted to check for upgrades every few weeks. If you would like oh-my-zsh to automatically upgrade itself without prompting you, set the following in you zshrc:

DISABLE_UPDATE_PROMPT=true

— After you are done with the above changes, press esc and type :wq to save the changes.
— Restart iTerm app.

Step 8:
Visual Changes in iTerm2 app

— Click on ‘iTerm2’ on menu bar and select ‘Preferences’.

— Set the following settings under “General” Tab.

— Set the following settings under “Appearances” Tab.

— Edit existing or set up a new profile under “Profiles” Tab.

  • Choose the following settings under ‘General’ tab.
  • Choose the following settings under “Window” Tab.
  • Choose the following settings under “Terminal” Tab.
  • Choose the following settings under “Session” Tab.

Click on “Configure Status Bar” button under “Session” Tab.

Drag “CPU Utilization”, “Memory Utilization” and “Network Throughput” widgets under “Active Components” section.

Step 9:
Installing Powerline fonts

Open iTerm2 and execute the following commands sequentially —

git clone https://github.com/powerline/fontscd fonts./install.sh

Fixing the issue mentioned in Step 6 —

  • Open terminal (not iTerm2, I am talking about the default “Terminal” app).
  • Go to “Preferences”, under “Text” subtab click on “Change” under “Font” section and select “Meslo LG L Regular for Powerline 11”.
  • Completely exit from Terminal app and restart it to check if the issue is resolved.

This fixes the issue mentioned in Step 6 in this article.

In case the above steps do not solve the issue, go through the link below to explore other possible solutions.

https://github.com/ohmyzsh/ohmyzsh/issues/1906#issuecomment-252443982

Step 8 (continued):
Visual Changes in iTerm2 app

  • Choose the following settings under “Text” Tab.

Select “Meslo LG S DZ Regular for Powerline” font for both. Since we had installed these fonts in Step 9, they should now be available.

  • Choose the following settings under “Colors” Tab.

RGB Hex for each color:

  • Basic Colors
    Foreground — fffaf5
    Background — 101321
    Bold — adaba9
    Links — 005bbb
    Selection — 00374b
    Selected Text — feffff
    Badge — ff2600
  • Cursor Colors:
    Cursor — ff261d
    Cursor Text — ff261d
    Cursor Guide — b3ecfff
  • ANSI Colors (Normal):
    Black — 2e2e2e
    Red — ff260d
    Green — 9ae204
    Yellow — ffc400
    Blue — 00a1f9
    Magenta — 805bb5
    Cyan — 00ddef
    White — feffff
  • ANSI Colors (Bright):
    Black — 555555
    Red — ff4250
    Green — b8e36d
    Yellow — ffd852
    Blue — 00a5ff
    Magenta — ab7aef
    Cyan — 74fcf3
    White — feffff

Restart iTerm application, now your terminal should be looking something like this 👇

Step 10:
Shortening username@hostname

Seeing this lengthy description isn’t really required each time we are going to type a command

paste the following lines of code in your .zshrc file and careful indent your code again

prompt_context() {
if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
prompt_segment black default "%(!.%{%F{yellow}%}.)$USER"
fi
}

Restart iTerm2 application, it should look like this-

much cleaner, unnecessary information no longer being displayed all the time

Now comes the PRODUCTIVITY part — Plugins!!

Although zsh ecosystem is filled with myriad plugins. But we will only be installing the ones which actually increase a developers productivity. (Installing a lot of plugins actually slows down shell.)

List of plugins available 👉 https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins

What we want to achieve?

  • Reduce the time spent in typing commands. My terminal should be able to predict what I want to type.
  • Be able to know when a mistake is being made in typing a command before I hit enter.
  • Be able to search through files and command line history just like I do in an IDE.

1. zsh-autosuggestions

ZSH autosuggestions plugin shows possible suggestions as you type based on your command history.

Link 👉 https://github.com/zsh-users/zsh-autosuggestions

Steps:

  • We need to clone the above repository into $ZSH_CUSTOM/plugins (by default ~/.oh-my-zsh/custom/plugins)
  • Use the following command-
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
  • Add the following two lines in .zshrc file (same way as explained in Step 7).
    (To enable a plugin, open your .zshrc file and scroll down until you see the spot where active plugins are defined. To add a new one, just type the name between the parentheses, making sure to include a space between each name.)
plugins=([already existing plugins...] zsh-autosuggestions)source ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
zsh-autosuggestions gives you suggestion as per your usage history. Within a short span of time, you will be using more and more of these autosuggestions rather than typing the entire command yourself.

2. zsh-syntax-highlighting

It highlights what you’re tying in real time.
1. If a program doesn’t exist, the text is red.
2. If a program does exist, the text is green.
3. It highlights matching brackets, text inside quotes, loads of stuff.

Link 👉 https://github.com/zsh-users/zsh-syntax-highlighting

Steps:

  • We need to clone the above repository into $ZSH_CUSTOM/plugins (by default ~/.oh-my-zsh/custom/plugins)
  • Use the following command-
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
  • Add the following two lines in .zshrc file (same way as explained in Step 7).
    (To enable a plugin, open your .zshrc file and scroll down until you see the spot where active plugins are defined. To add a new one, just type the name between the parentheses, making sure to include a space between each name.)
plugins=([already existing plugins...] zsh-syntax-highlighting)source ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
red highlighting on“gti” since git was misspelt

3. fzf

Fzf is a tiny, blazing fast, general-purpose command-line fuzzy finder, that helps you to search and open files quickly, go through command line history and much more.

Steps:

  • Execute the following command on your terminal:
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf && ~/.fzf/install
  • Remember to answer “y” to all questions.

— Now you can use Ctrl+T to search for files, like in your editor
— Also, you can now search for commands in your history too using Ctrl+R!

Bonus: tmux

Well, TMUX stands for “Terminal Multiplexer”. Without going into the details of what ”multiplexer” exactly means, let’s look at what it does and why is it so popular amongst serious devs.

  • One can leave his terminal sessions and come back to them without interrupting the running processes.
  • So, if you are on a remote computer, you can run some long installation process or a lengthy script in tmux, go offline (the computer, of course, needs to stay turned on), and come back later to see the results, e.g. the live terminal output.
  • One can manage a whole swarm of screens, split displays, dashboards at once.
  • The screen is organized in three layers as “sessions”, “windows”, and “panes”. You can maneuver many terminal screens with home-row friendly shortcuts and manipulate your workspace with scripts and hotkeys.

If you’re always working on just your desktop machine you might not realize it’s awesomeness. It really shines with remote connections or where it’s nice to have a persistent shell. (Basically a tabbed and windowed persistent shell session.)

How do you use it?

The following commands should help you to get started:

Tmux is available using brew on macOS.

  • Install tmux via HomeBrew
$ brew install tmux
  • After installation is complete, check the version
$ tmux -V
  • Start session
$ tmux
  • Start Session with the session name
$ tmux new-session -s <session_name_here>
  • Exit Session
$ exit
  • Attach to an already running session
$ tmux attach -t <session_name_here>
  • Split Vertically (will require changes in .tmux.conf file mentioned below)
Press CTRL + A keys, leave the keys and press = key
  • Split Horizontally (will require changes in .tmux.conf file mentioned below)
Press CTRL + A keys, leave the keys and press - key

Config file for tmux:

Create a file named .tmux.conf in your Home directory and copy-paste the folllowing contents in the file.

unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
bind = split-window -h
bind - split-window -v
unbind '"'
unbind %
set -g mouse onset -g @scroll-speed-num-lines-per-scroll 2

Note: This is the way I like my terminal, and I settled on this after several experiments. Feel free to explore other themes, plugins etc. The setup we discussed in this article is pretty minimal and only covers the essentials. I have also not covered setting up tmux, which I feel will probably require an article of its own.

Have an awesome Terminal experience!! 👨‍💻

If you have any feedback, reach out to me on Twitter, LinkedIn or Quora.

--

--

Abhinav Bhardwaj
codealchemist

Engineering @Uber | Ex-Zomato | DCEian | Software Developer | Open Source Enthusiast | Food Hogger | Student Forever