Skip to content

Instantly share code, notes, and snippets.

@mcfdn
Created July 3, 2025 20:13
Show Gist options
  • Save mcfdn/4c86eefd8cdc27043f58cf56b86d7645 to your computer and use it in GitHub Desktop.
Save mcfdn/4c86eefd8cdc27043f58cf56b86d7645 to your computer and use it in GitHub Desktop.
A basic Zsh prompt
# I got sick of bloated Oh My Zsh, so I switched to powerlevel10k.
# Now p10k is abandoned, so in an effort to reduce reliance on
# more plugins and dependencies, here's a basic prompt with no
# requirements (outside of the obvious git, etc).
#
# Looks like:
#
# ~/.config/zsh !130 &2
# $ ls -la 7ms
#
# ...where:
#
# [wd] ![non-zero exit code] &[n bg jobs]
# $ [prev. cmd time]ms
function precmd() {
# The previous exit code needs to be obtained before we do anything else,
# otherwise the wrong code may be displayed.
local prev_exit_code=$?
# Set prompt dir. More info in `man zshmisc` under `%~`.
local prompt_dir="%F{blue}%~%f "
# Display background jobs if any are running. More info in `man zshmisc`
# under `%j`.
local prompt_bg_jobs="%(1j.%F{cyan}&%j%f .)"
# Display the prompt character.
local prompt_char="%F{242}$%f "
# Display the current git branch if we're in a git repository.
local prompt_git_branch
if command git rev-parse --is-inside-work-tree &>/dev/null; then
# Get the current git branch name, falling back to commit hash if HEAD
# is detached.
local ref=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)
# Append an asterisk (*) if there are uncommitted changes.
local dirty=""
if [[ -n $ref ]]; then
if ! git diff --quiet --ignore-submodules --cached || ! git diff --quiet --ignore-submodules; then
dirty="%F{yellow}*%f"
fi
fi
# Append a caret (^) if the local branch is ahead of the upstream
# branch.
# First, check if the upstream branch exists.
local ahead=""
if git rev-parse --abbrev-ref --symbolic-full-name @{u} &>/dev/null; then
# Count the number of commits ahead of the upstream.
local commits_ahead=$(git rev-list --left-right --count HEAD...@{u} 2>/dev/null | awk '{print $1}')
if (( commits_ahead > 0 )); then
ahead="%F{yellow}^${commits_ahead}%f"
fi
fi
prompt_git_branch="%F{green}${ref}${dirty}${ahead}%f "
fi
# Display the exit code of the previous command if it was not 0.
local prompt_exit_code
if (( prev_exit_code != 0 )); then
prompt_exit_code="%F{167}!${prev_exit_code}%f "
fi
# Display the time taken for the last command to execute.
if [[ -n $__CMD_TIMER && -n $__CMD_DELTA ]]; then
local now=$(date +%s%3N)
__CMD_DELTA=$(($now-$__CMD_TIMER))
unset __CMD_TIMER
prompt_timer="%F{cyan}${__CMD_DELTA}ms%f"
fi
# Configure the main prompt (left).
export PROMPT="
${prompt_dir}${prompt_git_branch}${prompt_exit_code}${prompt_bg_jobs}
${prompt_char}"
# Configure the right prompt.
export RPROMPT="${prompt_timer}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment