DEV Community

Cover image for A better shell with oh-my-zsh
Codingones for Codingones

Posted on • Updated on

A better shell with oh-my-zsh

A better shell with oh-my-zsh

❓ Abstract

Not So Basic: Devenv is a series of tutorials where we aim to have a nice, productive and portable environment that take the best of both worlds between Linux and windows.

In this second tutorial "A better shell with oh-my-zsh" we do the groundwork using:

  • Zsh: a Linux shell with extended capabilities (command-line completion, command history, theming and much more...).
  • Oh My Zsh: a framework for managing Zsh configurations and theming.
  • Powerlevel10k: A quick, flexible and powerful theme for Zsh.

📝 Overview

To complete this tutorial, you need to:

Zsh and Oh My Zsh

Zsh

First you need to run the following commands to install zsh:



sudo apt update
sudo apt install zsh


Enter fullscreen mode Exit fullscreen mode

Oh My Zsh

Now you need to install Oh My Zsh.

Run the following command to install Oh My Zsh:



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


Enter fullscreen mode Exit fullscreen mode

Change the default shell

The default shell is the shell used when you start your terminal, to use zsh with the configuration we just set up, run:



chsh -s $(which zsh)


Enter fullscreen mode Exit fullscreen mode

Now run exit, it will close your current terminal, then open it again, you should be using zsh with your current theme.

A look on the default configuration.

You can find the default configuration file is in your home folder: ~/.zshrc

If you open it, you can see that most of it is commented.

A short version can be summarized as:



# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"

# Set name of the theme
ZSH_THEME="robbyrussel"

# Plugins
plugins=(git)

#import parent settings
source $ZSH/oh-my-zsh.sh


Enter fullscreen mode Exit fullscreen mode

Themes can add new features and nice display improvements.

Powerlevel10k

Install

Powerlevel10k is a full-featured theme for Zsh.

It's over 9000! Dbz meme

This theme offers the possibility to customize the style of your shell using many elements based on a font that includes icons.

Nerd fonts contains all the icons you need to have a good experience with the tool. You can check the features offered on the official nerd fonts website, select the font you prefer from the download page, or use the cheat sheet to search for an icon.

We will use FiraCode Nerd Font Mono in this tutorial because it is a monospaced programming font including typographic ligatures and well rendered by most of the terminals.

Install the recommended font on Windows

Download FiraCode Nerd Font, then follow the manual font installation instructions for your terminal.

Install the recommended font on Linux

Create a fonts directory in ~/.local/share



mkdir -p ~/.local/share/fonts


Enter fullscreen mode Exit fullscreen mode

Then you can download FiraCode Nerd Font:



wget https://github.com/ryanoasis/nerd-fonts/raw/refs/heads/master/patched-fonts/FiraCode/Bold/FiraCodeNerdFontMono-Bold.ttf -P ~/.local/share/fonts
wget https://github.com/ryanoasis/nerd-fonts/raw/refs/heads/master/patched-fonts/FiraCode/Light/FiraCodeNerdFontMono-Light.ttf -P ~/.local/share/fonts
wget https://github.com/ryanoasis/nerd-fonts/raw/refs/heads/master/patched-fonts/FiraCode/Medium/FiraCodeNerdFontMono-Medium.ttf -P ~/.local/share/fonts
wget https://github.com/ryanoasis/nerd-fonts/raw/refs/heads/master/patched-fonts/FiraCode/Regular/FiraCodeNerdFontMono-Regular.ttf -P ~/.local/share/fonts
wget https://github.com/ryanoasis/nerd-fonts/raw/refs/heads/master/patched-fonts/FiraCode/Retina/FiraCodeNerdFontMono-Retina.ttf -P ~/.local/share/fonts
wget https://github.com/ryanoasis/nerd-fonts/raw/refs/heads/master/patched-fonts/FiraCode/SemiBold/FiraCodeNerdFontMono-SemiBold.ttf -P ~/.local/share/fonts


Enter fullscreen mode Exit fullscreen mode

Finally, you can follow the manual font installation instructions for your terminal.

Install powerlevel10k as a Oh-my-zsh theme

Verify that git is present on your distribution:



git --version


Enter fullscreen mode Exit fullscreen mode

If git is not installed on your distribution, follow these instructions to install it, then run:



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


Enter fullscreen mode Exit fullscreen mode

Set ZSH_THEME="powerlevel10k/powerlevel10k" in ~/.zshrc



sed -i 's/ZSH_THEME="[^"]*/ZSH_THEME="powerlevel10k\/powerlevel10k/g' .zshrc


Enter fullscreen mode Exit fullscreen mode

Configure

Using the configuration wizard

When you exit and go back to your shell, you will be prompted by Powerlevel10k configuration wizard, follows the instructions to set up the configuration of your choice.

If you want to start again the configuration wizard, run:



p10k configure


Enter fullscreen mode Exit fullscreen mode

Manual advanced configuration

The configuration wizard is a nice starting point to quickly get a good-looking shell, but there is much more parameters you can fine-tune.

Here is an example of the result you can get at the end by following the Customization examples, which are taken from our p10k configuration file:

Custom shell

We will be glad to see the result of your own configuration, feel free to post a screenshot in the comments section!

You can use vim to explore and edit p10k configuration file, run the following command to install vim:



sudo apt install vim


Enter fullscreen mode Exit fullscreen mode

Here are some basic vim commands:

  • i to enter insert mode
  • escape to exit insert mode
  • / to enter a search term
  • enter to perform search
  • n to find the next occurrence or N to find the previous occurrence
  • escape to exit insert mode, then :wq and enter to save the file and quit vim
  • escape to exit insert mode, then :q! and enter to quit vim without saving
  • Read Getting started with Vim to learn the basics of this powerful cli file editor

Open p10k configuration file with vim:



vim ~/.p10k.zsh

Enter fullscreen mode Exit fullscreen mode




Customization examples

Switch a prompt segment from a side to another

For this example we will add the context user@hostname on the left prompt side and the vcs (git) segment to the right side.

Left prompt segments
  • Add context, not active by default on a local session, but we will change that later
  • Remove vcs to display it with right prompt segments ```bash=

typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
...
context # user@hostname
...
)

###### Right prompt segments

  • Remove context since it is now displayed with left prompt segments
  • Add vcs
  • Add contextual information about tools. Only displayed when installed and referenced by content of the current directory: Node.js, dotnet, PHP, Laravel, package
  • Add information about hardware on the next line ```bash=

typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(

=========================[ Line #1 ]=========================

vcs # git status
...
node_version # node.js version
dotnet_version # .NET version (https://dotnet.microsoft.com)
...
php_version # php version (https://www.php.net/)
laravel_version # laravel php framework version (https://laravel.com/)
...
package # name@version from package.json (https://docs.npmjs.com/files/package.json)
...

=========================[ Line #2 ]=========================

...
load # CPU load
ram # free RAM
disk_usage # disk usage
swap # used swap
battery # internal battery
wifi # wifi speed
...
)

Enter fullscreen mode Exit fullscreen mode



Change common colors

If your terminal support hexColors, you can override with the format var='hexCode'

In this example we:

  • Update some prompt segment background color
  • Update the color of prompt char displayed on the left following the previous command execution result
  • Update current directory colors
  • Update exit code of the last command
  • Update direnv status ```bash=

...
typeset -g POWERLEVEL9K_BACKGROUND='#232323'
...
typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR
{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_DIR_FOREGROUND='#92b7d4'
...
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND='#44637a'
...
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND='#6fa0c6'
...
typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR='#6fa0c6'
...
typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR='#6fa0c6'
...
typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_DIRENV_FOREGROUND='#6fa0c6'
...


Define VCS icons

You can override icons with the format var='charCode'
We create our own icons variables for the stashed/conflicted/staged/unstaged states.
In this example we:

...

Change the value of this parameter to show a different untracked file icon.

typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='\uf79f '

Change the value of this parameter to show a different stashed file icon.

typeset -g POWERLEVEL9K_VCS_STASHES_ICON='\uf187 '

Change the value of this parameter to show a different conflicted file icon.

typeset -g POWERLEVEL9K_VCS_CONFLICTED_ICON='\ufb8a '

Change the value of this parameter to show a different staged file icon.

typeset -g POWERLEVEL9K_VCS_STAGED_ICON='\uf005 '

Change the value of this parameter to show a different unstaged file icon.

typeset -g POWERLEVEL9K_VCS_UNSTAGED_ICON='\uf006 '
...

Enter fullscreen mode Exit fullscreen mode



Change VCS colors and icons

We will edit the my_git_formatter() original function

  • Update git status color ```bash=

...
function my_git_formatter() {
...
if (( $1 )); then
...
local clean='%F{#6fa0c6}' # blue foreground
local modified='%F{#e8c273}' # yellow foreground
local untracked='%F{#e1874d}' # orange foreground
local conflicted='%F{#d55555}' # red foreground
...
}



  • Update git status constants to use the previously defined icons variables (later in function) ```bash=

...
function my_git_formatter() {
...
(( VCS_STATUS_STASHES )) && res+=" ${clean}${(g::)POWERLEVEL9K_VCS_STATUS_STASHES_ICON}${VCS_STATUS_STASHES}"
...
(( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}${(g::)POWERLEVEL9K_VCS_CONFLICTED_ICON}${VCS_STATUS_NUM_CONFLICTED}"
...
(( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}${(g::)POWERLEVEL9K_VCS_STAGED_ICON}${VCS_STATUS_NUM_STAGED}"
...
(( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}${(g::)POWERLEVEL9K_VCS_UNSTAGED_ICON}${VCS_STATUS_NUM_UNSTAGED}"
...
}

Enter fullscreen mode Exit fullscreen mode



Package version format
  • Update current node package version format package-name:package-version


...
typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}:${P9K_PACKAGE_VERSION//\%/%%}'
...

Enter fullscreen mode Exit fullscreen mode



Hardware colors and configuration
  • Update disk usage colors
  • Update disk usage levels thresholds
  • Update disk usage display on warning
  • Update free ram color
  • Update used swap color
  • Update CPU load colors
  • Update battery colors
  • Update wifi colors
  • Update time colors ```bash=

...
typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND='#97b882'
typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND='#e1874d'
typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=80
typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=90
...
typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=true
...
typeset -g POWERLEVEL9K_RAM_FOREGROUND='#af7ca4'
...
typeset -g POWERLEVEL9K_SWAP_FOREGROUND='#e1874d'
...
typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND='#9090c0'
...
typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND='#e1874d'
...
typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_WIFI_FOREGROUND='#9fbfb4'
...
typeset -g POWERLEVEL9K_TIME_FOREGROUND='#76a394'
...


Context colors
  • Update context colors
  • Update context display to be always shown by commenting the relevant line ```bash=

...
typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND='#db6e51'
...
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND='#d55555'
...
typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND='#e8c273'
...

typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION=

...

Enter fullscreen mode Exit fullscreen mode



Development tools colors

...
typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND='#97b882'
...
typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND='#e4917a'
...
typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND='#b0b0d2'
...
typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND='#e8a478'
...
typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND='#c29cba'
...
typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND='#92b7d4'
...
typeset -g POWERLEVEL9K_NODENV_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_NVM_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_NODEENV_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND='#7ca661'
...
typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND='#9090c0'
...
typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND='#af7ca4'
...
typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND='#db6e51'
...
typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND='#e1874d'
...
typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND='#97b882'
...
typeset -g POWERLEVEL9K_JENV_FOREGROUND='#e1874d'
...
typeset -g POWERLEVEL9K_PHPENV_FOREGROUND='#af7ca4'
...
typeset -g POWERLEVEL9K_SCALAENV_FOREGROUND='#e8a478'


Change cloud tools colors

...
typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND='#727299'
...
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND='#5a82a1'
...
typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND='#ba7040'
...
typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND='#ba7040'
...
typeset -g POWERLEVEL9K_AZURE_FOREGROUND='#92b7d4'

Enter fullscreen mode Exit fullscreen mode




Next article

In the next article Improve your experience using git cli we will focus on customizing git.

Contributors

Romain Cambonie
Marc Gavanier

References used

Top comments (2)

Collapse
 
mitchstewart08 profile image
Mitchell Stewart

Fantastic article, helped me a lot with my oh-my-zsh journey on WSL2. Thanks!

Collapse
 
codingoneswriters profile image
Codingones

Happy to help, thank you for your kind comment :D