My zsh prompt - Phelipe Teles

My zsh prompt

2 min.
View source code

I’ve been happy with my Zsh prompt for some time now, it probably isn’t worth of a blog post but I did need to read the manual to come up with it so maybe it is.

Default

By default, it looks like this:

[No name]
phelipe @ ~/dotfiles %

If we don’t care about colors, the code for this would be

~/.zshrc
export PROMPT='%n @ %~ %#'

With colors

A zsh shell session with the prompt showing 'phelipe @ ~/Projetos/blog %' but now with colors

But we do care about colors, so let’s do that.

To give text a foreground color we surround it with %F{red}textf. And, similarly, to bold text we surround it with %Btext%b:

~/.zshrc
export PROMPT='\%B%F{green}%n %b%f\%B%F{yellow}@ %b%f\%B%F{blue}%~ %b%f\%B%F{black}%# %b%f\'

You can learn more about how to decorate your Zsh prompt in their manual.

Git integration

A zsh shell session with a prompt with git integration, showing the text '(master|REABASE 1/2)'

When on a git repository, an indicator with the branch name is shown:

[No name]
phelipe @ ~/dotfiles (master) %

If the branch name is too long, it’ll be truncated:

[No name]
phelipe @ ~/dotfiles (the-quick-brown-fox-jumps-over-the-l…) %

This is achieved using a shell function called __git_ps1, which is part of the Git project itself

It also indicates if you’re reverting, cherry-picking, rebasing, merging, bisecting etc.

[No name]
phelipe @ ~/dotfiles (master|REBASE 1/2) %

To display its output around parenthesis, we can pass a printf-like argument to it: __git_ps1 "(%s) ".

And to truncate it at 40 characters, we use a Zsh built-in feature. We mark the start of the truncation with %40>…) >, in which 40 is the maximum permitted length and …) is the truncation indicator. We mark the end of the truncated text with %<<.

~/.zshrc
export PROMPT='\%B%F{green}%n %b%f\%B%F{yellow}@ %b%f\%B%F{blue}%~ %b%f\%B%F{yellow}%40>…) >$(__git_ps1 "(%s) ")%<<%b%f\%B%F{black}%# %b%f\'

Background jobs

A zsh shell session with a prompt showing '*' as an indicator that there are jobs in the background

If there is a program running in the background, an asterisk is shown

[No name]
phelipe @ ~/dotfiles (master) * %

This is useful because I often let Vim in the background with <C-z> to do something in the terminal, and this serves as a reminder.

It works by using a Zsh built-in feature, a ternary-like expression with the condition being if is there at least one background jobs: %(1j.<true>.<false>):

~/.zshrc
export PROMPT='\%B%F{green}%n %b%f\%B%F{yellow}@ %b%f\%B%F{blue}%~ %b%f\%B%F{yellow}%40>…) >$(__git_ps1 "(%s) ")%<<%b%f\%B%F{green}%(1j.* .)%b%f\%B%F{black}%# %b%f\'

You can learn more about this conditional logic in Zsh prompt in the their manual.

Error indicator

A zsh shell session with a prompt with the '%' text in red because the last command execute was 'false'

Finally, the % symbol turns red if the last program executed exited with an error (a non-zero exit code).

To do this, we use the same ternary expression but using ? as the condition, which by default will be true if the exit status of the last command was 0:

~/.zshrc
export PROMPT='\%B%F{green}%n %b%f\%B%F{yellow}@ %b%f\%B%F{blue}%~ %b%f\%B%F{yellow}%40>…) >$(__git_ps1 "(%s) ")%<<%b%f\%B%F{green}%(1j.* .)%b%f\%B%F{%(?.black.red)}%# %b%f\'