Rewrite eriner theme using the Zim git-info module

Based on my rewrite of the Agnoster theme, uses simpler segment drawing
functions and only relies on local variables. Uses git-info module in
non-verbose mode, so a repo with only untracked files will not count as
dirty (but dirty state is computed faster). Also took the freedom of
adding an extra space character after the 'r' for the Ranger segment,
and after the dirty indicator for the Git segment. Everything else looks
and behaves exactly the same as the original prompt.
This commit is contained in:
Eric Nielsen 2017-03-01 15:18:16 -05:00 committed by Matt Hamilton
parent cf0bb77a37
commit a469e147cc
1 changed files with 66 additions and 117 deletions

View File

@ -1,160 +1,109 @@
# vim:ts=2 sw=2 sts=2 ft=zsh
#
# Eriner's Theme - fork of agnoster
# A Powerline-inspired theme for ZSH
#
# # README
#
# In order for this theme to render correctly, you will need a
# font with powerline symbols. A simple way to add the powerline
# symbols is to follow the instructions here:
# In order for this theme to render correctly, you will need a font with
# powerline symbols. A simple way to add the powerline symbols is to follow the
# instructions here:
# https://simplyian.com/2014/03/28/using-powerline-symbols-with-your-current-font/
#
# # 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.
#
# Uses the 'git-info' Zim module.
### Segment drawing
# A few utility functions to make it easy and re-usable to draw segmented prompts
# Utility functions to make it easy and re-usable to draw segmented prompts.
CURRENT_BG='NONE'
PRIMARY_FG=black
local prompt_eriner_bg
# Characters
function {
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
SEGMENT_SEPARATOR="\ue0b0"
PLUSMINUS="\u00b1"
BRANCH="\ue0a0"
DETACHED="\u27a6"
CROSS="\u2718"
LIGHTNING="\u26a1"
GEAR="\u2699"
# Begin a segment. Takes two arguments, background color and contents of the
# new segment.
prompt_eriner_segment() {
print -n "%K{$1}"
if [[ -n ${prompt_eriner_bg} ]]; then
print -n "%F{${prompt_eriner_bg}}"
fi
print -n "$2"
prompt_eriner_bg=$1
}
# 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
print -n "%{${bg}%F{${CURRENT_BG}}%}${SEGMENT_SEPARATOR}%{${fg}%}"
else
print -n "%{${bg}%}%{${fg}%}"
fi
CURRENT_BG=${1}
[[ -n ${3} ]] && print -n ${3}
}
# End the prompt, closing any open segments
prompt_end() {
if [[ -n $CURRENT_BG ]]; then
print -n "%{%k%F{${CURRENT_BG}}%}${SEGMENT_SEPARATOR}"
else
print -n "%{%k%}"
fi
print -n "%{%f%}"
CURRENT_BG=''
# End the prompt, closing last segment.
prompt_eriner_end() {
print -n "%k%F{${prompt_eriner_bg}}%f "
}
### Prompt components
# Each component will draw itself, and hide itself if no information needs to be shown
# Each component will draw itself, or hide itself if no information needs to be
# shown.
# Context: user@hostname (who am I and where am I)
prompt_context() {
if [[ ${USER} != ${DEFAULT_USER} || -n ${SSH_CONNECTION} ]]; then
prompt_segment ${PRIMARY_FG} default " %(!.%{%F{yellow}%}.)${USER}@%m "
# Status: Was there an error? Am I root? Are there background jobs? Ranger
# spawned shell? Who and where am I (user@hostname)?
prompt_eriner_status() {
local segment=''
(( ${RETVAL} )) && segment+=' %F{red}✘'
(( ${UID} == 0 )) && segment+=' %F{yellow}⚡'
(( $(jobs -l | wc -l) > 0 )) && segment+=' %F{cyan}⚙'
(( ${RANGER_LEVEL} )) && segment+=' %F{cyan}r'
if [[ ${USER} != ${DEFAULT_USER} || -n ${SSH_CLIENT} ]]; then
segment+=' %F{%(!.yellow.default)}${USER}@%m'
fi
if [[ -n ${segment} ]]; then
prompt_eriner_segment black "${segment} "
fi
}
# Ranger: <https://github.com/ranger/ranger>, which can spawn ${SHELL}
# under its own process
prompt_ranger() {
if [[ $((RANGER_LEVEL)) -ne 0 ]]; then
local color=blue
prompt_segment ${color} ${PRIMARY_FG}
print -Pn " r"
# Pwd: current working directory.
prompt_eriner_pwd() {
prompt_eriner_segment cyan " %F{black}$(short_pwd) "
}
# Git: branch/detached head, dirty status.
prompt_eriner_git() {
if [[ -n ${git_info} ]]; then
local indicator
[[ ${git_info[color]} == yellow ]] && indicator='± '
prompt_eriner_segment ${git_info[color]} " %F{black}${(e)git_info[prompt]} ${indicator}"
fi
}
# Git: branch/detached head, dirty status
prompt_git() {
local color ref
is_dirty() {
test -n "$(command git status --porcelain --ignore-submodules)"
}
ref=${vcs_info_msg_0_}
if [[ -n ${ref} ]]; then
if is_dirty; then
color=yellow
ref="${ref} ${PLUSMINUS}"
else
color=green
ref="${ref} "
fi
if [[ "${ref/.../}" == ${ref} ]]; then
ref="${BRANCH} ${ref}"
else
ref="$DETACHED ${ref/.../}"
fi
prompt_segment ${color} ${PRIMARY_FG}
print -Pn " ${ref}"
fi
}
# Dir: current working directory
prompt_dir() {
prompt_segment cyan ${PRIMARY_FG} " $(short_pwd) "
}
# Status:
# - was there an error
# - am I root
# - are there background jobs?
prompt_status() {
local symbols
symbols=()
[[ ${RETVAL} -ne 0 ]] && symbols+="%{%F{red}%}${CROSS}"
[[ ${UID} -eq 0 ]] && symbols+="%{%F{yellow}%}${LIGHTNING}"
[[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}${GEAR}"
[[ -n ${symbols} ]] && prompt_segment ${PRIMARY_FG} default " ${symbols} "
}
## Main prompt
### Main prompt
prompt_eriner_main() {
RETVAL=$?
CURRENT_BG='NONE'
prompt_status
prompt_context
prompt_ranger
prompt_dir
prompt_git
prompt_end
prompt_eriner_status
prompt_eriner_pwd
prompt_eriner_git
prompt_eriner_end
}
prompt_eriner_precmd() {
vcs_info
PROMPT='%{%f%b%k%}$(prompt_eriner_main) '
[[ ${+functions[git-info]} ]] && git-info
}
prompt_eriner_setup() {
autoload -Uz colors && colors
autoload -Uz add-zsh-hook
autoload -Uz vcs_info
prompt_opts=(cr subst percent)
prompt_opts=(cr percent subst)
add-zsh-hook precmd prompt_eriner_precmd
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' check-for-changes false
zstyle ':vcs_info:git*' formats '%b'
zstyle ':vcs_info:git*' actionformats '%b (%a)'
zstyle ':zim:git-info:branch' format ' %b'
zstyle ':zim:git-info:commit' format '➦ %c'
zstyle ':zim:git-info:action' format ' (%s)'
zstyle ':zim:git-info:clean' format 'green'
zstyle ':zim:git-info:dirty' format 'yellow'
zstyle ':zim:git-info:keys' format \
'prompt' '%b%c%s' \
'color' '%C%D'
PROMPT='${(e)$(prompt_eriner_main)}'
RPROMPT=''
}
prompt_eriner_setup "$@"