Skip to content

Instantly share code, notes, and snippets.

@Endevir
Last active October 22, 2025 17:58
Show Gist options
  • Select an option

  • Save Endevir/1820c518806d5ec1dc2a4fcf122f1e50 to your computer and use it in GitHub Desktop.

Select an option

Save Endevir/1820c518806d5ec1dc2a4fcf122f1e50 to your computer and use it in GitHub Desktop.
# Usage: prompt-length TEXT [COLUMNS]
#
# If you run `print -P TEXT`, how many characters will be printed
# on the last line?
#
# Or, equivalently, if you set PROMPT=TEXT with prompt_subst
# option unset, on which column will the cursor be?
#
# The second argument specifies terminal width. Defaults to the
# real terminal width.
#
# The result is stored in REPLY.
#
# Assumes that `%{%}` and `%G` don't lie.
#
# Examples:
#
# prompt-length '' => 0
# prompt-length 'abc' => 3
# prompt-length $'abc\nxy' => 2
# prompt-length '❎' => 2
# prompt-length $'\t' => 8
# prompt-length $'\u274E' => 2
# prompt-length '%F{red}abc' => 3
# prompt-length $'%{a\b%Gb%}' => 1
# prompt-length '%D' => 8
# prompt-length '%1(l..ab)' => 2
# prompt-length '%(!.a.)' => 1 if root, 0 if not
function prompt-length() {
emulate -L zsh
local -i COLUMNS=${2:-COLUMNS}
local -i x y=${#1} m
if (( y )); then
while (( ${${(%):-$1%$y(l.1.0)}[-1]} )); do
x=y
(( y *= 2 ))
done
while (( y > x + 1 )); do
(( m = x + (y - x) / 2 ))
(( ${${(%):-$1%$m(l.x.y)}[-1]} = m ))
done
fi
typeset -g REPLY=$x
}
# Usage: fill-line LEFT RIGHT
#
# Sets REPLY to LEFT<spaces>RIGHT with enough spaces in
# the middle to fill a terminal line.
function fill-line() {
emulate -L zsh
prompt-length $1
local -i left_len=REPLY
prompt-length $2 9999
local -i right_len=REPLY
local -i pad_len=$((COLUMNS - left_len - right_len - ${ZLE_RPROMPT_INDENT:-1}))
if (( pad_len < 1 )); then
# Not enough space for the right part. Drop it.
typeset -g REPLY=$1
else
local pad=${(pl.$pad_len.. .)} # pad_len spaces
typeset -g REPLY=${1}${pad}${2}
fi
}
# Sets PROMPT and RPROMPT.
#
# Requires: prompt_percent and no_prompt_subst.
function set-prompt() {
emulate -L zsh
ZSH_THEME_GIT_PROMPT_PREFIX="«"
ZSH_THEME_GIT_PROMPT_SUFFIX=":$(git_prompt_short_sha)» %{$reset_color%}"
# Previous command return code
local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
# Current time
local current_time="%{$fg[yellow]%}%T%{$reset_color%}"
# User
if (($UID == 0)) then
local my_user="%{$terminfo[bold]$fg[red]%}%n%{$reset_color%}"
local my_prompt="%{$fg[red]%}#%{$reset_color%}"
else
local my_user="%{$fg[green]%}%n%{$reset_color%}"
local my_prompt="%{$fg[green]%}$%{$reset_color%}"
fi
# Kubernetes
local kubernetes="%{$fg[cyan]%}($ZSH_KUBECTL_PROMPT)%{$reset_color%}"
# Host
local host="%{$fg[cyan]%}%m%{$reset_color%}"
# Git
local git_info=''
local git_space=''
local git_color=''
if git_prompt_info &> /dev/null; then
git_space=' '
git_info="$(git_prompt_info)"
fi
local git_branch="$(git symbolic-ref -q HEAD 2>/dev/null | cut -d "/" -f 3-)"
case "${git_branch}" in
master)
git_color="%{$fg[cyan]%}" ;;
hotfix*)
git_color="%{$fg[red]%}" ;;
release*)
git_color="%{$fg[green]%}" ;;
develop)
git_color="%{$fg[yellow]%}" ;;
*)
if [[ -n "${git_branch}" ]] ; then
git_color="%{$fg[magenta]%}"
else
git_color="%{$fg[white]%}"
fi
;;
esac
# Directory
local current_dir="%{$fg[blue]%}%d%{$reset_color%}"
local top_left="╭──${my_user}@${host}${git_space}${git_color}${git_info}"
local bottom_left="╰─>${current_dir}${my_prompt} "
local top_right="${kubernetes}"
local bottom_right=""
local REPLY
fill-line "$top_left" "$top_right"
PROMPT=$REPLY$'\n'$bottom_left
RPROMPT=$bottom_right
}
setopt no_prompt_{bang,subst} prompt_{cr,percent,sp}
autoload -Uz add-zsh-hook
add-zsh-hook precmd set-prompt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment