Create a gist now

Instantly share code, notes, and snippets.

My ZSH Theme

agnoster.zsh-theme

A ZSH theme optimized for people who use:

  • Solarized
  • Git
  • Unicode-compatible fonts and terminals (I use iTerm2 + Menlo)

For Mac users, I highly recommend iTerm 2 + Solarized Dark

Compatibility

NOTE: In all likelihood, you will need to install a Powerline-patched font for this theme to render correctly.

To test if your terminal and font support it, check that all the necessary characters are supported by copying the following command to your terminal: echo "⮀ ± ⭠ ➦ ✔ ✘ ⚡". The result should look like this:

Character Example

What does it show?

  • If the previous command failed (✘)
  • User @ Hostname
  • Git status
    • Current branch / SHA1 in detached head state
    • Dirty working directory (color change)
    • Up/Down/Both arrows when branch is in ahead,behind or diverged
    • show different other glyph's when files in a git repo are unracked, modified, added, deleted, renamed and unmerged
  • Working directory

Screenshot

Future Work

I don't want to clutter it up too much, but I am toying with the idea of adding RVM (ruby version), Java Version and date/time.

# original theme https://gist.github.com/3750104
# from https://github.com/agnoster
#
# vim:ft=zsh ts=2 sw=2 sts=2
#
# 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](https://gist.github.com/1595572).
#
# In addition, I recommend the
# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
# using it on Mac OS X, [iTerm 2](http://www.iterm2.com/) 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.
new_line() {
echo ''
}
CURRENT_BG=''
prompt_segment() {
if [[ -n $CURRENT_BG ]]; then
close_previous_segment $CURRENT_BG $1
fi
local bg fg
bg="%K{$1}"
fg="%F{$2}"
echo -n "%{$bg%}%{$fg%}"
echo -n " "
echo -n $3
echo -n " "
CURRENT_BG=$1
}
close_previous_segment() {
local separator=$(echo -e "\xe2\xae\x80")
bg="%K{$2}"
fg="%F{$1}"
echo -n "%{$bg%}%{$fg%}"
echo -n $separator
}
prompt_command_status() {
local ballot_x=$(echo -e "\xe2\x9c\x98")
local check_mark=$(echo -e "\xe2\x9c\x94")
local symbols
[[ $LAST_CMD_STATUS -ne 0 ]] && symbols+="%{%F{red}%}$ballot_x"
[[ $LAST_CMD_STATUS -eq 0 ]] && symbols+="%{%F{green}%}$check_mark"
prompt_segment black default "$symbols $LAST_CMD_STATUS %h"
}
reset_colors() {
echo -n "%{%k%}"
echo -n "%{%f%}"
}
enable_bold() {
echo -n "%{%f%B%k%}"
}
prompt_user() {
prompt_segment black default %n@%m
}
prompt_dir() {
prompt_segment blue black "%~"
}
prompt_end() {
if [[ -n $CURRENT_BG ]]; then
close_previous_segment $CURRENT_BG default
fi
}
prompt_git() {
if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
ZSH_THEME_GIT_PROMPT_MODIFIED=" %{$(echo -e "\xe2\x9a\x99")%}"
ZSH_THEME_GIT_PROMPT_DELETED=" %{$(echo -e "\xe2\x9c\x98")%}"
ZSH_THEME_GIT_PROMPT_UNTRACKED=" %{$(echo -e "\x3f")%}"
ZSH_THEME_GIT_PROMPT_UNMERGED=" %{$(echo -e "\xe2\x9a\xa1")%}"
ZSH_THEME_GIT_PROMPT_RENAMED=" %{$(echo -e "\xe2\x9c\x8e")%}"
ZSH_THEME_GIT_PROMPT_ADDED=" %{$(echo -e "\xe2\x98\x85")%}"
ZSH_THEME_GIT_PROMPT_SUFFIX=""
ZSH_THEME_GIT_PROMPT_PREFIX="%{$(echo -e "\xc2\xb1")%}"
ZSH_THEME_GIT_PROMPT_DIRTY=":"
ZSH_THEME_GIT_PROMPT_CLEAN=""
ZSH_THEME_GIT_PROMPT_AHEAD=" %{$(echo -e "\xe2\x86\x91")%}"
ZSH_THEME_GIT_PROMPT_BEHIND=" %{$(echo -e "\xe2\x86\x93")%}"
ZSH_THEME_GIT_PROMPT_DIVERGED=" %{$(echo -e "\xe2\x86\x95")%}"
if [[ -n $(parse_git_dirty) ]]; then
prompt_segment yellow black "$(git_prompt_info)$(git_prompt_status)"
else
prompt_segment green black "$(git_prompt_info)$(git_prompt_status)"
fi
fi
}
space() {
echo -n ' '
}
comma() {
echo -n ', '
}
command_exists () {
type "$1" &> /dev/null ;
}
prompt_system() {
echo -n 'zsh-'$ZSH_VERSION
if command_exists brew; then
comma
echo -n 'brew-'`brew --version`
fi
if command_exists mysql; then
comma
echo -n 'mysql-'`mysql --version | awk '{print $5}'`
fi
if command_exists git; then
space
echo -n 'git-'`git --version | awk '{print $3}'`
fi
if command_exists rvm; then
comma
echo -n 'rvm-'`rvm --version 2>&1 | grep rvm | awk '{print $2}'`
fi
}
prompt_lang() {
if command_exists ruby; then
echo -n 'ruby-'`ruby --version | awk '{print $2}'`
fi
if command_exists python; then
comma
echo -n 'python-'`python --version 2>&1 | awk '{print $2}'`
fi
if command_exists java; then
comma
echo -n 'java-'`java -version 2>&1 | grep version | awk '{print $3}' | sed 's/"//g'`
fi
}
build_info_line() {
new_line
new_line
echo -n '['
prompt_system
echo -n ']'
echo -n ' '
echo -n '['
prompt_lang
echo -n ']'
}
build_powerline() {
new_line
enable_bold
prompt_command_status
prompt_user
prompt_dir
prompt_git
prompt_end
reset_colors
new_line
echo -n '%# '
}
build_date_time() {
echo -n "%{$fg[red]%} %w,%t"
reset_colors
}
build_all_prompts() {
LAST_CMD_STATUS=$?
build_info_line
build_powerline
}
PROMPT='$(build_all_prompts)'
RPROMPT='$(build_date_time)'
# vim:ft=zsh ts=2 sw=2 sts=2
#
# 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](https://gist.github.com/1595572).
#
# In addition, I recommend the
# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
# using it on Mac OS X, [iTerm 2](http://www.iterm2.com/) 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'
SEGMENT_SEPARATOR='‚ÆÄ'
# 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 != $CURRENT_BG ]]; then
echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
else
echo -n "%{$bg%}%{$fg%} "
fi
CURRENT_BG=$1
[[ -n $3 ]] && echo -n $3
}
# End the prompt, closing any open segments
prompt_end() {
if [[ -n $CURRENT_BG ]]; then
echo -n " %{%k%F{$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() {
local user=`whoami`
if [[ "$user" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
prompt_segment black default "%(!.%{%F{yellow}%}.)$user@%m"
fi
}
# Git: branch/detached head, dirty status
prompt_git() {
local ref dirty
if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
ZSH_THEME_GIT_PROMPT_DIRTY='±'
dirty=$(parse_git_dirty)
ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="‚û¶ $(git show-ref --head -s --abbrev |head -n1 2> /dev/null)"
if [[ -n $dirty ]]; then
prompt_segment yellow black
else
prompt_segment green black
fi
echo -n "${ref/refs\/heads\//⭠ }$dirty"
fi
}
# Dir: current working directory
prompt_dir() {
prompt_segment blue black '%~'
}
# Status:
# - was there an error
# - am I root
# - are there background jobs?
prompt_status() {
local symbols
symbols=()
[[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}‚úò"
[[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}‚ö°"
[[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}‚öô"
[[ -n "$symbols" ]] && prompt_segment black default "$symbols"
}
## Main prompt
build_prompt() {
RETVAL=$?
prompt_status
prompt_context
prompt_dir
prompt_git
prompt_end
}
PROMPT='%{%f%b%k%}$(build_prompt) '
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment