Skip to content

Instantly share code, notes, and snippets.

@kljensen
Created December 30, 2025 12:20
Show Gist options
  • Select an option

  • Save kljensen/b431d6be6c56a4f5465a799a37ce1f65 to your computer and use it in GitHub Desktop.

Select an option

Save kljensen/b431d6be6c56a4f5465a799a37ce1f65 to your computer and use it in GitHub Desktop.
Minimal Powerline Prompt for Zsh - p10k replacement in ~100 lines
# Minimal Powerline Prompt for Zsh
# Features: OS icon, directory, git branch, exit status
# No external dependencies
# Powerline characters
local PL_ARROW=$'\uE0B0' #
local PL_ARROW_LEFT=$'\uE0B2' #
local PL_BRANCH=$'\uF126' #
# Colors (matching original p10k rainbow theme)
local C_OS_FG=232 # black
local C_OS_BG=7 # white/gray
local C_DIR_FG=254 # white
local C_DIR_BG=4 # blue/cyan
local C_GIT_FG=0 # black
local C_GIT_CLEAN_BG=2 # green
local C_GIT_DIRTY_BG=3 # yellow
local C_OK_FG=2 # green
local C_ERR_FG=1 # red
local C_FRAME=240 # gray for frame chars
# Git branch (updated in precmd)
typeset -g _prompt_git_branch=""
typeset -g _prompt_git_bg=$C_GIT_CLEAN_BG
_prompt_update_git() {
local branch
branch=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)
if [[ -n "$branch" ]]; then
_prompt_git_branch="$branch"
# Check if dirty (has uncommitted changes)
if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null; then
_prompt_git_bg=$C_GIT_CLEAN_BG
else
_prompt_git_bg=$C_GIT_DIRTY_BG
fi
else
_prompt_git_branch=""
fi
}
# Build the prompt segments
_prompt_build() {
local left="" left_len=0
local last_bg=""
# Helper to add left segment
_seg() {
local fg=$1 bg=$2 content=$3
if [[ -n "$last_bg" ]]; then
left+="%F{$last_bg}%K{$bg}${PL_ARROW}%f"
((left_len+=1)) # arrow char
else
left+="%K{$bg}"
fi
left+="%F{$fg} ${content} %f"
last_bg=$bg
}
# OS Icon segment
_seg $C_OS_FG $C_OS_BG ""
((left_len+=3)) # space + icon + space
# Directory segment
local dir_expanded="${(%):-%(5~|%-1~/…/%3~|%~)}"
_seg $C_DIR_FG $C_DIR_BG "$dir_expanded"
((left_len+=${#dir_expanded}+2)) # content + spaces
# Git segment (if in repo)
if [[ -n "$_prompt_git_branch" ]]; then
_seg $C_GIT_FG $_prompt_git_bg "${PL_BRANCH} ${_prompt_git_branch}"
((left_len+=${#_prompt_git_branch}+4)) # icon + space + branch + spaces
fi
# End left prompt
left+="%F{$last_bg}%k${PL_ARROW}%f"
((left_len+=1)) # final arrow
# Frame chars add 2 to left
((left_len+=2)) # ╭─
# Right side: status (4 visible chars: arrow + space + icon + space)
local right_len=4
local status_ok="%F{$C_OK_FG}${PL_ARROW_LEFT}%K{$C_OK_FG}%F{0} ✔ %f%k"
local status_err="%F{$C_ERR_FG}${PL_ARROW_LEFT}%K{$C_ERR_FG}%F{255} ✘ %f%k"
local status_seg="%(?.$status_ok.$status_err)"
# Calculate gap fill
local gap=$((COLUMNS - left_len - right_len))
((gap < 1)) && gap=1
local fill="${(l:$gap::─:)}"
# Build two-line prompt with frame
PROMPT=$'\n' # Empty line before prompt
PROMPT+="%F{$C_FRAME}╭─%f" # Top-left frame
PROMPT+="${left}" # Left segments
PROMPT+="%F{$C_FRAME}${fill}%f" # Gap fill
PROMPT+="${status_seg}" # Status right-aligned
PROMPT+=$'\n' # Newline
PROMPT+="%F{$C_FRAME}╰─%f" # Bottom-left frame
PROMPT+="%(?..%F{$C_ERR_FG})❯%f " # Prompt char (red if error)
RPROMPT=""
}
# Hook to update prompt before each command
_prompt_precmd() {
_prompt_update_git
_prompt_build
}
# Register the hook
autoload -Uz add-zsh-hook
add-zsh-hook precmd _prompt_precmd
# Initial build
_prompt_precmd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment