Engineering Programming

Terminal setup using ZSH, Prezto and Starship on MacOS

Terminal setup using ZSH, Prezto and Starship on MacOS

ZSH installation#

Starting with Catalina the default shell was changed to zsh. You can verify your current shell using:

 echo $SHELL
/bin/zsh

If it’s not zsh for you, you can install it using Homebrew

brew install zsh

Once installed we need to make zsh the default shell using:

chsh -s /bin/zsh

Prezto installation#

Prezto is a configuration framework for zsh. Another well known alternative is Oh My Zsh.

I was using Oh My Zsh previously but it had performance issues and switching to Prezto has helped with the performance issues. Oh My Zsh has a much bigger community and receives regular updates and is bit more beginner friendly.

Before installing make sure to make a back of your .zshrc file if you had one already as Prezto can ve problematic with existing .zshrc files.

Clone the Prezto repo#

git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done

Once installed you’ll find the Prezto configuration in .zpreztorc file in your home directory. The default file looks like this: https://github.com/sorin-ionescu/prezto/blob/master/runcoms/zpreztorc

The list of modules are available here: https://github.com/sorin-ionescu/prezto/blob/master/runcoms/zpreztorc

zstyle ':prezto:load' pmodule \
 'lazy-load' \
 'environment' \
 'terminal' \
 'editor' \
 'history' \
 'directory' \
 'spectrum' \
 'utility' \
 'completion' \
 'osx' \
 'ssh' \
 'git' \
 'python' \
 'node' \
 'syntax-highlighting' \
 'history-substring-search' \
 'prompt' \
 'autosuggestions'

Here lazy-load is a 3rd party module to lazily load functions that are time consuming: https://github.com/xcv58/zsh-lazy-load

To install this module if you want, do the following:

cd $HOME/.zprezto
git submodule add https://github.com/xcv58/zsh-lazy-load.git modules/lazy-load

Once that is done 'lazy-load' should be the first item in your modules list as shown above.

In my current .zshrc file I’m using it to lazily load nvm and virtualenvwrapper:

# .zshrc

func load_virtualenv() {
  source path_to_virtualenvwrapper.sh
}

func load_nvm () {
    source path_to_nvm.sh
}


# At the end of .zshrc
lazy_load load_virtualenv load_nvm

Selecting theme#

Prezto comes with a bunch of themes. To list the themes use prompt -l and to preview one use prompt -p name. Once you’ve picked a theme open your .zpreztorc file and add it zstyle ':prezto:module:prompt' theme 'pure' (here 'pure' is the prompt theme’s name).

Fonts#

Currently, I’m using GitHub’s Monaspace font, its Krypton variation. This font supports ligatures.

Other fonts I highly recommend:

  • Nerd font — great for terminal prompt
  • Fira Code (supports ligatures)
  • Monaco (ships with MacOS and great for code but lacks ligatures). A ligature version is also available but I’ve not tried it personally. The Powerline mentioned here is a prompt theme.

Font setup in iTerm 2:

Font setup in iTerm 2

Font setup in VS Code:

Font setup in VS Code

Ligatures setup in VS Code

Prompt Customization#

I’m using Starship for customizing the prompt. Note that by default it requires Nerd Font.

To install it Homebrew can be used:

brew install starship

Then open your .zshrc file and add the following at the end:

eval "$(starship init zsh)"

To configure Starship you need to create a config file first:

mkdir -p ~/.config && touch ~/.config/starship.toml

Then define the items you’d want:

format = """
$custom\
$username\
$hostname\
$shlvl\
$directory\
$git_branch\
$git_commit\
$git_state\
$git_status\
$package\
$elixir\
$golang\
$nodejs\
$python\
$ruby\
$rust\
$terraform\
$nix_shell\
$aws\
$env_var\
$line_break\
$status\n\
$cmd_duration\
$character"""
add_newline = true

Then for each item you can further make your own modification, for example here’s how username, directory and git status looks like for me:

[username]
disabled = false
show_always = true
style_user = "white bold"
style_root = "white bold"
format = "[xonix_$user]($style) "

[directory]
truncation_length = 100  # no truncation
truncate_to_repo = true
format = "[$path]($style) "

## Git settings
[git_branch]
style = "bold purple"
truncation_length = 100  # no truncation
truncation_symbol = "..."

[custom.xonix]
command = "echo -n '🍺 '"
when = "true"

The resulting prompt looks like:

Starship configured prompt

The setting available under any such action is in the docs: username, directory, git_branch and custom

Find detailed documentation here: https://starship.rs/config/#prompt

Checking performance#

If your shell is taking a while to load then it can be profiled by adding zmodload zsh/zprof at the start of .zshrc file and zprof at the end of the file. In addition individual modules can be timed using time (pmodload '<module_name>').

Ashwini Chaudhary

Written by Ashwini Chaudhary

Software engineer, writer, and photographer.

Comments