A simple but powerful zsh prompt

Over the years, I’ve been changing my bash prompt every now and then. Since I switched to zsh last year, and started using oh-my-zsh, I’ve slowly put together the perfect prompt for my needs.

Here’s how it looks right now (with extra-large font size for better visibility):

zsh prompt

Parts of the left prompt, from left to right:

  • 1z shows that there is one background job (vim), suspended with Ctrl+Z (hence the z) — this goes away if there are no background jobs
  • tp is the hostname, useful to tell apart ssh sessions
  • git:master shows that I’m in a git repo and that master is the currently active branch, this one is very useful
  • after the git branch indicates that there are unstaged changes or newly added files — this goes away in a clean tree
  • ~/github.com/attilaolah/… is just the $PWD collapsed with ~ when applicable
  • $ shows that I’m not the root user
  • there’s a trailing space to make it a word boundary when selecting with the mouse

There are spaces between these parts so that I can select them with a double-click, if I want to quickly navigate here, for example in another tmux window.

Parts of the right prompt, from right to left:

  • 1:23:52 is the time, which is useful when I forget to prefix a long running command with time
  • = before the time indicates a non-zero exit status from the previous command

I used to have git_prompt_status in the right prompt (that shows a summary of changes in the current repo), but it was making the terminal noticeably slower, which is not something I tolerate. Hitting enter in a terminal must feel instant.

The source, if anyone likes it:

ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[blue]%}git%{$reset_color%}:%{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%}…%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_CLEAN=""

local prompt_jobs="%(1j.%{$fg[yellow]%}%j%{$reset_color%}%{$fg[red]%}z%{$reset_color%} .)"
local prompt_host="%{$fg[cyan]%}%m%{$reset_color%}"
local prompt_root="%(!.%{$fg_bold[red]%}#.%{$fg[green]%}$)%{$reset_color%}"

local return_status="%{$fg[red]%}%(?..=)%{$reset_color%}"

PROMPT='${prompt_jobs}${prompt_host}$(git_prompt_info) %~ ${prompt_root} '

RPROMPT="${return_status}%*"