Writing ZSH Themes: A Quickref

Posted on by in Development

Customizing your terminal is a fun way to streamline and personalize your digital workspace. People are more productive when using tools they enjoy and tend to value things they made themselves at a premium, but, as with all technical adventures, it can also be a little tedious to track down all the relevant documentation. This tutorial assumes you’re using zsh as your terminal shell. If you’re not sure what shell you’re using, the following will print the default shell path:

$ echo $SHELL

If the output is something like /bin/zsh then read on! Otherwise please make sure that you have zsh installed and set as your default login shell before continuing. Zsh introduces many features, but there’s a popular library called oh-my-zsh which adds even more convenience methods on top of zsh. Installation instructions are on the homepage:

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

Most of this tutorial will work without oh-my-zsh, but I’ll point out which customizations rely on it. Now that you have your shell, let’s get ready to customize!

Theme installation with oh-my-zsh

One of the most popular features of oh-my-zsh is its built-in theme tooling. If you’re using oh-my-zsh you can keep your themes in the ~/.oh-my-zsh/themes directory as a .zsh-theme file. You’ll see that this directory is prepopulated with over 100 themes already! You can use any of these predefined themes, or follow this guide to create your own. Even if you plan on making your own, these can be a good inspiration or reference for the look you want to achieve. The active theme is defined in your ~/.zshrc file (your general-purpose zsh configuration file) by the variable called ZSH_THEME. The theme file in the theme directory corresponding to this value will be your active theme. For example, you might see ZSH_THEME=robbyrussell in your ~/.zshrc file, which means your terminal will use the theme described in ~/.oh-my-zsh/themes/robbyrussell.zsh-theme. Try changing the ZSH_THEME to theunraveler, then source ~/.zshrc in your terminal and see what happens!

Create and install a custom theme in just 3 easy steps!

  1. Create a .zsh-theme file in that directory and write your theme using the guide below
  2. Set ZSH_THEME=your-theme-name in your ~/.zshrc file
  3. $ source ~/.zshrc in your terminal to refresh your zsh profile

Sometimes you will follow this guide to the letter and your theme will still not seem to update or render as expected… try closing your terminal and opening a fresh terminal window! Sometimes your shell accidentally holds onto outdated variables and turning it off and on again should reset everything fresh ✨ That’s it! In the next section I will provide a quick reference for some basic zsh theme properties you may want to use. If the quick reference lacks context for you at any point, check out the examples provided below it to get you started!

Quick reference

The quickref can be viewed full screen here.

Example 1: Basic shell

PROMPT=’$ ‘
RPROMPT=’’

Example 2: Informative shell

# purple username
username() {
   echo "%{$FG[012]%}%n%{$reset_color%}"
}

# current directory, two levels deep
directory() {
   echo "%2~"
}

# current time with milliseconds
current_time() {
   echo "%*"
}

# returns 👾 if there are errors, nothing otherwise
return_status() {
   echo "%(?..👾)"
}

# set the git_prompt_info text
ZSH_THEME_GIT_PROMPT_PREFIX="("
ZSH_THEME_GIT_PROMPT_SUFFIX=")"
ZSH_THEME_GIT_PROMPT_DIRTY="*"
ZSH_THEME_GIT_PROMPT_CLEAN=""

# putting it all together
PROMPT='%B$(username) $(directory)$(git_prompt_info)%b '
RPROMPT='$(current_time)$(return_status)'

Example 3: Arrows

right_triangle() {
   echo $'\ue0b0'
}

prompt_indicator() {
   echo $'%B\u276f%b'
}

arrow_start() {
   echo "%{$FG[$ARROW_FG]%}%{$BG[$ARROW_BG]%}%B"
}

arrow_end() {
   echo "%b%{$reset_color%}%{$FG[$NEXT_ARROW_FG]%}%{$BG[$NEXT_ARROW_BG]%}$(right_triangle)%{$reset_color%}"
}

ok_username() {
   ARROW_FG="016"
   ARROW_BG="015"
   NEXT_ARROW_BG="183"
   NEXT_ARROW_FG="015"
   echo "$(arrow_start) %n $(arrow_end)"
}

err_username() {
   ARROW_FG="016"
   ARROW_BG="160"
   NEXT_ARROW_BG="183"
   NEXT_ARROW_FG="160"
   echo "$(arrow_start) %n $(arrow_end)"
}

# return err_username if there are errors, ok_username otherwise
username() {
   echo "%(?.$(ok_username).$(err_username))"
}

directory() {
   ARROW_FG="016"
   ARROW_BG="183"
   NEXT_ARROW_BG="139"
   NEXT_ARROW_FG="183"
   echo "$(arrow_start) %2~ $(arrow_end)"
}

current_time() {
   echo "%{$fg[white]%}%*%{$reset_color%}"
}

git_prompt() {
   ARROW_FG="016"
   ARROW_BG="139"
   NEXT_ARROW_BG=""
   NEXT_ARROW_FG="096"
   echo "$(arrow_start) $(git_prompt_info) $(arrow_end)"
}

# set the git_prompt_info text
ZSH_THEME_GIT_PROMPT_PREFIX=""
ZSH_THEME_GIT_PROMPT_SUFFIX=""
ZSH_THEME_GIT_PROMPT_DIRTY="*"
ZSH_THEME_GIT_PROMPT_CLEAN=""

# set the git_prompt_status text
ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[cyan]%} ✈%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%} ✭%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✗%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%} ➦%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[magenta]%} ✂%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[white]%} ✱%{$reset_color%}"

PROMPT='$(username)$(directory)$(git_prompt)
$(prompt_indicator) '
RPROMPT='$(git_prompt_status) $(current_time)'

Resources & References


Interested in more software development tips and insights? Visit the development section on our blog!

 

Now hiring developers, designers, and product managers. Apply now: www.carbonfive.com/careers