vim:ft=zsh ts=2 sw=2 sts=2
February 25, 2021 · View on GitHub
agnoster's Theme - https://gist.github.com/3712874
A Powerline-inspired theme for ZSH
# README
In order for this theme to render correctly, you will need a
Powerline-patched font.
Make sure you have a recent version: the code points that Powerline
uses changed in 2012, and older versions will display incorrectly,
in confusing ways.
In addition, I recommend the
Solarized theme and, if you're
using it on Mac OS X, iTerm 2 over Terminal.app -
it has significantly better color fidelity.
# Goals
The aim of this theme is to only show you relevant information. Like most
prompts, it will only show git information when in a git working directory.
However, it goes a step further: everything from the current user and
hostname to whether the last call exited with an error to whether background
jobs are running in this shell will all be displayed automatically when
appropriate.
Segment drawing
A few utility functions to make it easy and re-usable to draw segmented prompts
CURRENT_BG='NONE'
Special Powerline characters
() { local LC_ALL="" LC_CTYPE="en_US.UTF-8"
NOTE: This segment separator character is correct. In 2012, Powerline changed
the code points they use for their special characters. This is the new code point.
If this is not working for you, you probably have an old version of the
Powerline-patched fonts installed. Download and install the new version.
Do not submit PRs to change this unless you have reviewed the Powerline code point
history and have new information.
This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of
what font the user is viewing this source code in. Do not replace the
escape sequence with a single literal character.
Do not change this! Do not make it '\u2b80'; that is the old, wrong code point.
SEGMENT_SEPARATOR=$'\ue0b0' }
Begin a segment
Takes two arguments, background and foreground. Both can be omitted,
rendering default background/foreground.
prompt_segment() { local bg fg [[ -n $1 ]] && bg="%K{$1}" || bg="%k" [[ -n $2 ]] && fg="%F{$2}" || fg="%f" if [[ CURRENT_BG != 'NONE' && \1 != bg%F{CURRENT_BG}%}SEGMENT_SEPARATOR%{bg%}%{fg%} " fi CURRENT_BG=\1 [[ -n $3 ]] && echo -n $3 }
End the prompt, closing any open segments
prompt_end() { if [[ -n CURRENT_BG}%}$SEGMENT_SEPARATOR" else echo -n "%{%k%}" fi echo -n "%{%f%}" CURRENT_BG='' }
Prompt components
Each component will draw itself, and hide itself if no information needs to be shown
Context: user@hostname (who am I and where am I)
prompt_context() { if [[ "DEFAULT_USER" || -n "USER" fi }
Git: branch/detached head, dirty status
prompt_git() { (( +commands[git] )) || return local PL_BRANCH_CHAR () { local LC_ALL="" LC_CTYPE="en_US.UTF-8" PL_BRANCH_CHAR='\ue0a0' # } local ref dirty mode repo_path repo_path=$(git rev-parse --git-dir 2>/dev/null)
if (git rev-parse --is-inside-work-tree >/dev/null 2>&1); then dirty=(parse_git_dirty) ref=(git rev-parse --short HEAD 2> /dev/null)" if [[ -n $dirty ]]; then prompt_segment yellow black else prompt_segment green black fi
if [[ -e "${repo_path}/BISECT_LOG" ]]; then
mode=" <B>"
elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then
mode=" >M<"
elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then
mode=" >R>"
fi
setopt promptsubst
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' get-revision true
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:*' stagedstr '✚'
zstyle ':vcs_info:*' unstagedstr '●'
zstyle ':vcs_info:*' formats ' %u%c'
zstyle ':vcs_info:*' actionformats ' %u%c'
vcs_info
local BRANCH_NAME="${ref/refs\/heads\/}${vcs_info_msg_0_%% }${mode}"
if [[ "$BRANCH_NAME" =~ ^([A-Z]+-[0-9]+) ]]; then # shorten jira slugs
echo -n "$PL_BRANCH_CHAR $match[1]\u2026"
if [[ "$BRANCH_NAME" =~ " (.+)$" ]]; then
echo -n " $match[1]"
fi
else
echo -n "$PL_BRANCH_CHAR $BRANCH_NAME"
fi
fi }
prompt_bzr() { (( +commands[bzr] )) || return if (bzr status >/dev/null 2>&1); then status_mod=`bzr status | head -n1 | grep "modified" | wc -m` status_all=`bzr status | head -n1 | wc -m` revision=`bzr log | head -n2 | tail -n1 | sed 's/^revno: //'` if [[ status_mod -gt 0 ]] ; then prompt_segment yellow black echo -n "bzr@"status_all -gt 0 ]] ; then prompt_segment yellow black echo -n "bzr@"$revision
else
prompt_segment green black
echo -n "bzr@"$revision
fi
fi
fi
}
prompt_hg() { (( (hg id >/dev/null 2>&1); then if (hg prompt >/dev/null 2>&1); then if [[ (hg prompt "{status|unknown}") = "?" ]]; then # if files are not added prompt_segment red white st='±' elif [[ -n (hg prompt "{status|modified}") ]]; then # if any modification prompt_segment yellow black st='±' else # if working copy is clean prompt_segment green black fi echo -n (hg prompt "☿ {rev}@{branch}") (hg id -n 2>/dev/null | sed 's/[^-0-9]//g') branch=rev@st fi fi }
Dir: current working directory
prompt_dir() { if [[ -v CURRENT_PROJECT_DIR && -v CURRENT_PROJECT_NAME && PWD =~ "^CURRENT_PROJECT_DIR(.*)CURRENT_PROJECT_NAME$match[1]" else prompt_segment blue black '%~' fi }
Virtualenv: current working virtualenv
prompt_virtualenv() { local virtualenv_path="virtualenv_path && -n virtualenv_path`)" fi }
nix-shell: currently running nix-shell
prompt_nix_shell() { if [[ -n "NIX_SHELL_PACKAGES ]]; then local package_names="" local packages=(packages; do package_names+=" {package##*.}" done prompt_segment black yellow "{package_names }" elif [[ -n {name#interactive-} cleanName={cleanName#lorri-keep-env-hack-} cleanName={cleanName%-environment} prompt_segment black yellow "{ $cleanName }" else # This case is only reached if the nix-shell plugin isn't installed or failed in some way prompt_segment black yellow "nix-shell {}" fi fi }
Status:
- was there an error
- am I root
- are there background jobs?
prompt_status() { local symbols symbols=() [[ RETVAL -ne 0 && RETVAL -ne 1 ]] && symbols+="%{%F{red}%}RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘" [[ UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡" [[ (jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"
if [ {#symbols[@]} -ne 0 ]; then prompt_segment black default "symbols" fi }
Main prompt
build_prompt() { RETVAL=$? prompt_status prompt_nix_shell prompt_virtualenv prompt_context prompt_dir prompt_git prompt_bzr prompt_hg prompt_end }
PROMPT='%{%f%b%k%}$(build_prompt) '