How to Build a Beautiful and Practical macOS Terminal

The terminal is an essential tool for development, but the default macOS terminal is rather plain in both appearance and functionality. This article will guide you on how to use tools like iTerm2, Oh My Zsh, and Powerlevel10k to create a beautiful and practical macOS terminal. Before we begin, let’s take a look at the final result.

Before proceeding, it is recommended to back up your existing configurations.

1
2
cp ~/.zshrc ~/.zshrc.bak
cp ~/.vimrc ~/.vimrc.bak

iTerm2

iTerm2 is a replacement for the macOS terminal with more features. First, we need to download the latest version from https://iterm2.com/downloads.html.

Next, extract the downloaded zip file and drag the resulting iTerm file to the “Applications” folder.

Open iTerm2, and in the menu bar, click iTerm2 -> Settings... to enter the settings page.

First, go to the General -> Selection tab and modify the settings as shown in the image below.

Then, go to the Profiles -> Keys -> Key Mappings tab, click Presets... -> Natural Text Editing.

However, as of the time of writing this article, the Natural Text Editing preset in iTerm2 has an issue where ⌥ Option + ⌫ Backspace cannot delete a word. To fix this, we need to double-click to edit the key mapping for ⌥←Delete, removing the double quotes in the Hex Code, as shown below.

Some of these key mappings are natively supported by Zsh, while others need to be used in conjunction with the bindkey command in the ~/.zshrc configuration file. We will cover how to configure this later.

Next, go to the Profiles -> Window tab and modify the settings as shown in the image below. Note that if you don’t like the translucent effect, you only need to set Columns and Rows.

Before proceeding, we need to install the Meslo Nerd Font. Download the following font files:

Go to the download folder, select all the font files, right-click, choose “Open,” and then click “Install.”

Now, go back to the iTerm2 settings page, enter the Profiles -> Text tab, and modify the settings as shown in the image below.

The Powerlevel10k theme, which we will install later, requires these fonts to display correctly.

Before the final step, we need to prepare a color scheme. You can go to https://iterm2colorschemes.com/ to download your favorite color scheme, or use my color scheme (right-click the link in your browser and choose “Save As”).

Now, go back to the iTerm2 settings page, enter the Profiles -> Colors tab, click Color Presets... -> Import..., select the color scheme you just downloaded, and then click Color Presets... again to select the imported color scheme.

Customizing Vim

If you don’t use Vim, you can skip this step.

As the saying goes, “A craftsman must sharpen his tools to do his work well.” In the following steps, we will frequently use the Vim editor to modify various configuration files, so we need to make some improvements to Vim. We will use the following tools:

First, we need to run the following command in the terminal to download Vundle:

1
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

Next, we need to create the ~/.vimrc file and enter the following content to enable Vundle and let it install various plugins:

1
vi ~/.vimrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
set nocompatible              " be iMproved, required
filetype off " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

Plugin 'morhetz/gruvbox'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'

" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList - lists configured plugins
" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line

syntax on
colorscheme gruvbox

let g:airline_theme='simple'
let g:airline_powerline_fonts=1
let g:airline#extensions#tabline#enabled=1

Finally, let’s open Vim. It will throw an error because our color scheme hasn’t been installed as a plugin yet. We can simply press Enter to enter Vim, then run the :PluginInstall command to install the plugins. After exiting Vim and reopening it, everything should work fine.

Customizing Zsh

Oh My Zsh is a popular Zsh configuration management tool. We need to run the following command in the terminal to install it:

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

Oh My Zsh supports numerous plugins and themes. Some of my favorite plugins are:

We need to run the following commands in the terminal to download them:

1
2
3
4
git clone https://github.com/TamCore/autoupdate-oh-my-zsh-plugins ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/autoupdate
git clone https://github.com/zdharma-continuum/fast-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/fast-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-history-substring-search ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-history-substring-search

As for the theme, I prefer Powerlevel10k. We need to run the following command in the terminal to download it:

1
git clone https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

Next, we need to edit the ~/.zshrc file to enable Powerlevel10k:

1
vi ~/.zshrc
1
2
3
4
5
6
@@ -8,7 +8,7 @@ export ZSH="$HOME/.oh-my-zsh"
# load a random theme each time Oh My Zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
-ZSH_THEME="robbyrussell"
+ZSH_THEME="powerlevel10k/powerlevel10k"

After closing the current iTerm2 window or tab and reopening it, you will automatically enter the Powerlevel10k configuration process.

1
p10k configure

You can choose different styles according to your preferences, or you can refer to my configuration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Does this look like a diamond (rotated square)?
(y) Yes.

Does this look like a lock?
(y) Yes.

Does this look like an upwards arrow?
(y) Yes.

What digit is the downwards arrow pointing to?
(1) It is pointing at '1'.

Do all these icons fit between the crosses?
(y) Yes. Icons are very close to the crosses but there is no overlap.

Prompt Style
(3) Rainbow.

Character Set
(1) Unicode.

Show current time?
(2) 24-hour format.

Prompt Separators
(4) Round.

Prompt Heads
(5) Round.

Prompt Tails
(5) Round.

Prompt Height
(2) Two lines.

Prompt Connection
(3) Solid.

Prompt Frame
(1) No frame.

Connection Color
(2) Light.

Prompt Spacing
(1) Compact.

Icons
(2) Many icons.

Prompt Flow
(1) Concise.

Enable transient prompt?
(n) No.

Instant Prompt Mode
(1) Verbose (recommended).

Apply changes to ~/.zshrc?
(y) Yes (recommended).

After the configuration process is complete, Powerlevel10k will automatically update the ~/.zshrc file. We need to edit the ~/.zshrc file again to enable various plugins:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@@ -67,7 +67,7 @@ ZSH_THEME="powerlevel10k/powerlevel10k"
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
-# HIST_STAMPS="mm/dd/yyyy"
+HIST_STAMPS="yyyy-mm-dd"

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
@@ -77,7 +77,7 @@ ZSH_THEME="powerlevel10k/powerlevel10k"
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
-plugins=(git)
+plugins=(git vi-mode z autoupdate fast-syntax-highlighting zsh-autosuggestions zsh-history-substring-search)

source $ZSH/oh-my-zsh.sh

@@ -109,6 +109,20 @@ source $ZSH/oh-my-zsh.sh
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
+alias zshconfig="vi ~/.zshrc"
+alias p10kconfig="vi ~/.p10k.zsh"
+alias sshconfig="vi ~/.ssh/config"
+alias sshhosts="vi ~/.ssh/known_hosts"
+
+# Key bindings
+bindkey '^P' history-substring-search-up
+bindkey '^N' history-substring-search-down
+
+# Require the Natural Text Editing preset in iTerm2
+bindkey '^U' kill-whole-line
+bindkey '^[b' backward-word
+bindkey '^[f' forward-word
+bindkey '^\x1b\x7f' backward-kill-word

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

Here, I have set up some of my commonly used aliases, as well as bindkeys that work with iTerm2’s key mappings and the zsh-history-substring-search plugin. You can modify these according to your needs, but please keep these bindkeys.

Finally, we need to edit the ~/.p10k.zsh file to fine-tune the colors of Powerlevel10k:

1
vi ~/.p10k.zsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@@ -96,7 +96,7 @@
midnight_commander # midnight commander shell (https://midnight-commander.org/)
nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html)
chezmoi_shell # chezmoi shell (https://www.chezmoi.io/)
- # vi_mode # vi mode (you don't need this if you've enabled prompt_char)
+ vi_mode # vi mode (you don't need this if you've enabled prompt_char)
# vpn_ip # virtual private network indicator
# load # CPU load
# disk_usage # disk usage
@@ -841,16 +841,16 @@
typeset -g POWERLEVEL9K_VI_MODE_FOREGROUND=0
# Text and color for normal (a.k.a. command) vi mode.
typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL
- typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2
+ typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=4
# Text and color for visual vi mode.
typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL
- typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=4
+ typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=3
# Text and color for overtype (a.k.a. overwrite and replace) vi mode.
typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE
- typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=3
+ typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=9
# Text and color for insert vi mode.
- typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING=
- typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=8
+ typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING=INSERT
+ typeset -g POWERLEVEL9K_VI_MODE_INSERT_BACKGROUND=2
# Custom icon.
# typeset -g POWERLEVEL9K_VI_MODE_VISUAL_IDENTIFIER_EXPANSION='⭐'

Here, I mainly modified the status bar colors for vi-mode to make it more noticeable. You can also modify it according to your preferences.

The last line’s FOREGROUND needs to be changed to BACKGROUND, so please double-check.

Common Issues

If you also use terminal in IDEs, you may encounter some font display issues. Here, we use Visual Studio Code as an example. We need to press ⌘ Command + , to open the settings, search for terminal.integrated.fontFamily, and modify the font to MesloLGS NF.

Common Usage Tips

Here are some commonly used features and shortcuts.

  • ⌃ Control + A / ⌘ Command + ← Move to the beginning of the line
  • ⌃ Control + E / ⌘ Command + → Move to the end of the line
  • ⌥ Option + ← Move one word to the left
  • ⌥ Option + → Move one word to the right
  • ⌃ Control + U / ⌘ Command + ⌫ Backspace Delete the entire line
  • ⌃ Control + W / ⌥ Option + ⌫ Backspace Delete one word
  • ⌃ Control + L Clear the screen

The zsh-autosuggestions plugin will search the history in real-time as you type and display gray suggestions. You can use / ⌃ Control + E / ⌘ Command + → to accept the suggestion, or use ⌥ Option + → to accept one word.

The zsh-history-substring-search plugin allows you to search through your history. You just need to type part of a command, then use ⌃ Control + P / ⌃ Control + N to search for the previous or next match.

The git plugin simplifies Git commands, for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gst  # git status
gb # git branch
gba # git branch -a
gbd # git branch -d
gbD # git branch -D
ga # git add
gaa # git add --all
gcm # git commit -m
gco # git checkout
gsw # git switch
gf # git fetch
gfa # git fetch --all
gl # git pull
gp # git push
gpf # git push --force

The z plugin records the directories you frequently visit. You can use z [directory path keyword] to quickly jump to the target directory, saving time compared to using the cd command to type the full path.

The autoupdate-zsh-plugin plugin will automatically update plugins and themes. You can also use the upgrade_oh_my_zsh_custom command to manually update them.


How to Build a Beautiful and Practical macOS Terminal
https://tomzhu.site/2025/03/17/How-to-Build-a-Beautiful-and-Practical-macOS-Terminal/
作者
Tom Zhu
发布于
2025年3月18日
许可协议