Customizing the prompt

Zsh · Practical · 10 min

A good prompt shows where you are, which branch you are on and whether the last command failed.

The prompt is the PROMPT variable (alias PS1); RPROMPT is shown on the right and disappears as you type into it. Zsh expands percent escapes in them:

  • %n user, %m short host name, %~ current directory with ~ for home, %1~ only its last component,
  • %# shows # for root and % otherwise, %? the last exit status, %T the time,
  • %F{red}...%f foreground colour (names or 0-255), %B...%b bold,
  • %(?.yes.no) a conditional: here "yes" if the last command succeeded.

To include the output of variables or functions that change, set PROMPT_SUBST and write the prompt in single quotes, so ${...} is expanded every time the prompt is drawn rather than once when .zshrc runs.

For the git branch, zsh ships vcs_info: load it, call vcs_info from the precmd hook (run before each prompt), and use $vcs_info_msg_0_. Its formats style uses %b for the branch; it can also show staged or unstaged changes.

print -P '...' expands prompt escapes so you can experiment. If you prefer a ready-made prompt, Powerlevel10k and the cross-shell Starship are popular, but understanding the escapes lets you read and tweak them.

Example

autoload -Uz vcs_info
precmd() { vcs_info }                       # refresh before each prompt
zstyle ':vcs_info:git:*' formats ' (%b)'    # %b = branch name
setopt PROMPT_SUBST
PROMPT='%F{cyan}%n@%m%f %F{yellow}%~%f${vcs_info_msg_0_} %(?.%F{green}.%F{red})%#%f '
RPROMPT='%F{240}%T%f'                       # time on the right
print -P '%F{yellow}%~%f'                   # try escapes: ~/projects/app
print -P 'last: %(?.ok.failed with %?)'     # last: ok
# The result looks like:
# ada@laptop ~/projects/app (main) %                     12:41

Remember

  • %n %m %~ %# %? are the core prompt escapes
  • %F{color}...%f for colour, %(?.ok.fail) for conditionals
  • PROMPT_SUBST plus single quotes for values that change, vcs_info for git

Watch out for

  • Writing PROMPT in double quotes with ${...}, so the value is frozen when .zshrc runs.

Check yourself

  1. What does %(?.✔.✘) show after a failing command?
  2. Why is the prompt written in single quotes with PROMPT_SUBST set?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html

Builds on

Unlocks

Nothing builds on this yet.