2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Chauncey Garrett
# @vrtcl1dvoshun
# 21 May 2013
#
# Garrett Zsh Theme for Prezto
# Created with modified code by Chauncey Garrett
# (ver.2013.05.21.15.17.46)
#
# A prompt full of information when you need it and absent when you don't.
#
# This prompt has the following features:
# - change prompt color when UID is root
# - change host color when on SSH
# - display full or truncated hostname on SSH
# - determine the number of background jobs
# - report the present working directory
# - report return codes
# - report local time
# - report the terminal line number
# - report git status, git remote status, git prompt info and git SHA information
# - indicate vi-mode
2013-06-08 11:46:33 -05:00
# - growl notifications for commands taking longer than x time
2013-05-22 17:07:24 -05:00
#
# Features may be disabled and rearranged as desired by using the corresponding tokens.
# —————————————————————————————————————————————————————————————————————
# —————————————————————————————————————————————————————————————————————
# Load dependencies
# —————————————————————————————————————————————————————————————————————
pmodload 'helper'
# —————————————————————————————————————————————————————————————————————
# Help function
# TODO not even remotely finished...
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_help() {
2013-06-18 16:03:48 -05:00
cat <<'EOF'
2013-05-22 17:07:24 -05:00
This prompt is configurable via styles:
2013-06-18 16:03:48 -05:00
Context: :prompt:garrett
2013-05-22 17:07:24 -05:00
2013-06-18 16:03:48 -05:00
Colors (red green yellow blue magenta cyan white grey):
color_user | The color for user@host. Defaults to 'green'
root_color | The color for the hostname for root. Defaults to 'red'
color_prompt | The color for everything else. Defaults to ''
2013-05-22 17:07:24 -05:00
2013-06-18 16:03:48 -05:00
Path (path type - possible values):
ratio - use COLUMNS/ratio to clip the path. Default.
fixed - use a fixed maximum lenght.
subdir - clip by number of subdirectories.
full - show the full path
2013-05-22 17:07:24 -05:00
2013-06-18 16:03:48 -05:00
Path length styles:
ratio | the ratio for the 'ratio' path style, funnily enough. Defaults to 6.
length | the maximum length for the 'fixed' path style. Defaults to 20.
subdir | the number of subdirs to show for the 'subdir' path style. Defaults to 3.
2013-05-22 17:07:24 -05:00
2013-06-18 16:03:48 -05:00
You can set styles in the current terminal to test things out, values will be updated.
2013-05-22 17:07:24 -05:00
EOF
}
# —————————————————————————————————————————————————————————————————————
# Preview
2013-06-18 16:03:48 -05:00
# TODO not ready
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_preview {
2013-06-18 16:03:48 -05:00
if (( $# > 0 )); then
prompt_preview_theme 'garrett' "$@"
else
prompt_preview_theme 'garrett' #red green blue
# print
# prompt_preview_theme 'garrett' yellow magenta black
fi
2013-05-22 17:07:24 -05:00
}
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# PWD truncation precmd function
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_pwd {
2013-06-18 16:03:48 -05:00
local pwd="${PWD/#$HOME/~}"
2013-06-08 11:46:33 -05:00
2013-05-22 17:07:24 -05:00
if [[ "$pwd" == (#m)[/~] ]]; then
2013-06-18 16:03:48 -05:00
current_dir="${color_pwd}$MATCH"
2013-05-22 17:07:24 -05:00
unset MATCH
else
2013-06-18 16:03:48 -05:00
current_dir="${color_pwd}${${${(@j:/:M)${(@s:/:)pwd}##.#?}:h}%/}/${pwd:t}"
2013-05-22 17:07:24 -05:00
fi
}
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# Determine number of background jobs precmd function
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
function prompt_garrett_number_jobs {
2013-06-21 00:47:05 -05:00
number_jobs="%(1j.${color_prompt}J:${cyan}%j.) "
2013-05-22 17:07:24 -05:00
}
2013-06-18 16:03:48 -05:00
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-08 11:46:33 -05:00
# Growl Notifications after x amount of time has passed
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_growl_preexec {
# Define timer and cmd for growl notification
export PREEXEC_TIME=$(date +'%s')
export PREEXEC_CMD="The command: $1"
}
function prompt_garrett_growl_precmd {
# Trigger a growl notification after x time has elapsed
DELAY_AFTER_NOTIFICATION=1
# Determine x time elapsed
start=${PREEXEC_TIME:-`date +'%s'`}
stop=$(date +'%s')
let elapsed=$stop-$start
# growlnotify!
if [ $elapsed -gt $DELAY_AFTER_NOTIFICATION ]; then # x time has passed so growlnotify!
tput bel
growlnotify -n "Terminal" -m "Took $elapsed s" ${PREEXEC_CMD:-Some command}
fi
}
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# PROMPT chpwd
# - a function which is executed whenever the directory is changed
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_chpwd {
emulate -L zsh # TODO can't remember why this is necessary...
ls -AG # list the contents of the new directory
}
# —————————————————————————————————————————————————————————————————————
# PROMPT preexec (Before command execution)
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_preexec {
# —————————————————————————————————————————————————————————————————————
# Define timer and cmd for growl notification
# —————————————————————————————————————————————————————————————————————
if (( $+commands[growlnotify] )); then
export PREEXEC_TIME=$(date +'%s')
export PREEXEC_CMD="The command: $1"
fi
# —————————————————————————————————————————————————————————————————————
# Ensure terminal code isn't colored from prompt
# —————————————————————————————————————————————————————————————————————
print -n "$reset_color"
}
# —————————————————————————————————————————————————————————————————————
# PROMPT precmd (After command execution)
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_precmd {
setopt LOCAL_OPTIONS
unsetopt XTRACE KSH_ARRAYS
2013-06-18 16:03:48 -05:00
# —————————————————————————————————————————————————————————————————————
# Show number of background jobs
# —————————————————————————————————————————————————————————————————————
prompt_garrett_number_jobs
# —————————————————————————————————————————————————————————————————————
# Format PWD
# —————————————————————————————————————————————————————————————————————
prompt_garrett_pwd
2013-06-08 11:46:33 -05:00
2013-06-18 16:03:48 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-08 11:46:33 -05:00
# Trigger a growl notification after x time has elapsed
2013-06-18 16:03:48 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-08 11:46:33 -05:00
if (( $+commands[growlnotify] )); then
eval prompt_garrett_growl_precmd
fi
2013-06-18 16:03:48 -05:00
# —————————————————————————————————————————————————————————————————————
2013-05-22 17:07:24 -05:00
# Get ruby info
2013-06-18 16:03:48 -05:00
# —————————————————————————————————————————————————————————————————————
2013-05-22 17:07:24 -05:00
if (( $+functions[ruby-info] )); then
2013-06-08 11:46:33 -05:00
ruby-info
2013-05-22 17:07:24 -05:00
fi
2013-06-08 11:46:33 -05:00
2013-06-18 16:03:48 -05:00
# —————————————————————————————————————————————————————————————————————
# Get git repository info
# —————————————————————————————————————————————————————————————————————
if (( $+functions[git-info] )); then
git-info
fi
# —————————————————————————————————————————————————————————————————————
# Add a line to prompt for visibility
# —————————————————————————————————————————————————————————————————————
local prompt_width_term
(( prompt_width_term= ${COLUMNS} - 1 ))
# Determine the length needed for prompt_space
# NOTE: Be sure not to include the ${(e)prompt_space} portion or it won't work
2013-07-12 00:16:21 -05:00
local prompt_line1="${altchar_upper_left_corner}( ${current_dir}${git_info[remote_status]}${git_info[prompt_info]}${git_info[local_status]}${git_info[sha]} )( ${ruby_info[version]}${location} )${altchar_upper_right_corner}"
2013-06-18 16:03:48 -05:00
local zero='%([BSUbfksu]|([FB]|){*})'
local prompt_width_line1=${#${(S%%)prompt_line1//$~zero/}}
local prompt_space_padding
(( prompt_space_padding= ${prompt_width_term} - ${prompt_width_line1} ))
2013-07-12 00:16:21 -05:00
local prompt_space_character="${altchar_padding}"
2013-06-18 16:03:48 -05:00
eval prompt_space="${color_prompt}\${(l.${prompt_space_padding}..${prompt_space_character}.)}"
# —————————————————————————————————————————————————————————————————————
# Prompt line 1
# —————————————————————————————————————————————————————————————————————
print
2013-07-12 00:16:21 -05:00
print -P '${altchar_enable}${color_prompt}${altchar_upper_left_corner}( ${current_dir}${git_info[remote_status]}${git_info[prompt_info]}${git_info[local_status]}${git_info[sha]} ${color_prompt})${altchar_enter}${(e)prompt_space}${altchar_leave}( ${ruby_info[version]}${location}${color_prompt} )${altchar_upper_right_corner}'
2013-05-22 17:07:24 -05:00
}
# —————————————————————————————————————————————————————————————————————
# Setup prompt
# —————————————————————————————————————————————————————————————————————
function prompt_garrett_setup {
# —————————————————————————————————————————————————————————————————————
# Load necessary modules
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
setopt LOCAL_OPTIONS
unsetopt XTRACE KSH_ARRAYS
prompt_opts=(cr percent subst)
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Add hook for calling precommand & chpwd
# —————————————————————————————————————————————————————————————————————
autoload -Uz add-zsh-hook
2013-06-18 16:03:48 -05:00
add-zsh-hook preexec prompt_garrett_preexec
2013-05-22 17:07:24 -05:00
add-zsh-hook precmd prompt_garrett_precmd
add-zsh-hook chpwd prompt_garrett_chpwd
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# Colors
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# Alias the colors
[[ -z $(functions colors) ]] && autoload -U colors && colors
typeset -Ag FX FG BG
for color in black red green yellow blue magenta cyan white grey; do
eval $color='%F{${(L)color}}'
eval ${color}_BOLD='%B{${(L)color}}'
2013-05-22 17:07:24 -05:00
done
2013-06-18 16:03:48 -05:00
for color in {000..255}; do
FG[$color]="%F [38;5;${color}m"
BG[$color]="%K [48;5;${color}m"
done
FX=(
reset "%{ [00m%}"
bold "%B" no-bold "%b"
italic "%{ [03m%}" no-italic "%{ [23m%}"
underline "%U" no-underline "%u"
blink "%{ [05m%}" no-blink "%{ [25m%}"
reverse "%{ [07m%}" no-reverse "%{ [27m%}"
standout "%S" no-standout "%s"
)
# Show all 256 colors with color number
function spectrum_ls() {
for code in {000..255}; do
print -P -- "$code: %K{$code} %k %F{$code} Lorem ipsum...%f"
done
}
# Color scheme
eval color_pwd=\$\{${2:-'blue'}\}
# eval color_pwd=${2:-'${blue}'}
eval color_line_number=${5:-'${magenta}'}
eval color_time=${6:-'${green}'}
eval color_git_branch=${7:-'${green}'}
eval color_git_sha=${8:-'${yellow}'}
eval color_ruby_version=${8:-'${yellow}'}
# Determine prompt, user and host colors
if [[ "$EUID" = "0" ]] || [[ "$USER" = 'root' ]]; then # root user
eval color_user=${3:-'${red}'}
eval color_host=${3:-'${red}'}
eval color_prompt=${3:-'${red}'}
# eval color_prompt_BOLD=${3:-'${red_BOLD}'}
eval user='%S${color_user}%n%s'
elif [[ -n "$SSH_CLIENT" || -n "$SSH2_CLIENT" ]]; then # on SSH
eval color_user=${3:-'${green}'}
eval color_host=${3:-'${yellow}'}
eval color_prompt=${3:-'${yellow}'}
# eval color_prompt_BOLD=${3:-'${yellow_BOLD}'}
eval user='%S${color_user}%n%s'
2013-05-22 17:07:24 -05:00
else # normal user
2013-06-18 16:03:48 -05:00
eval color_user=${1:-'${green}'}
eval color_host=${1:-'${green}'}
2013-07-12 00:16:21 -05:00
eval color_prompt=${1:-'${grey}'}
2013-06-18 16:03:48 -05:00
# eval color_prompt_BOLD=${1:-'${white}'}
eval user=''
# eval user='${color_user}%n'
2013-05-22 17:07:24 -05:00
fi
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# Report hostname
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
eval host='${color_host}%m' # hostname up to first . (dot)
# eval host='${color_host}%M' # full hostname
2013-05-22 17:07:24 -05:00
eval location='${user}${cyan}@${host}' # hostname with user
# —————————————————————————————————————————————————————————————————————
# Report return code
# —————————————————————————————————————————————————————————————————————
2013-06-21 00:47:05 -05:00
eval return_code='%(?..${red}%? ↵ ) '
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Report local time
# —————————————————————————————————————————————————————————————————————
eval current_time='${green}%T' # 24 hour time format
2013-06-21 00:47:05 -05:00
# eval current_time='${green}%*' # 24 hour time format, precise
2013-06-18 16:03:48 -05:00
# eval current_time='${green}%t' # AM/PM time format
2013-06-21 00:47:05 -05:00
# Keep the time updated
# schedprompt() {
# emulate -L zsh
# zmodload -i zsh/sched
# # Remove existing event, so that multiple calls to "schedprompt" work OK (you could put one in precmd to push the timer 30 seconds into the future, for example.)
# integer i=${"${(@)zsh_scheduled_events#*:*:}"[(i)schedprompt]}
# (( i )) && sched -$i
# # Test that zle is running before calling the widget (recommended to avoid error messages). Otherwise it updates on entry to zle, so there's no loss.
# zle && zle reset-prompt
# # This ensures we're not too far off the start of the minute
# sched +1 schedprompt
# }
# schedprompt
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Report terminal line number
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
eval line_number='${green}+${magenta}%!'
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# Report git info
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# zstyle ':prezto:module:git:info' verbose 'yes'
2013-05-22 17:07:24 -05:00
2013-06-18 16:03:48 -05:00
# Git prompt info (in order in which it will appear in the prompt)
2013-08-20 16:33:12 -05:00
zstyle ':prezto:module:git:info:branch' format "${cyan} λ${color_prompt}:${green}%b"
2013-06-18 16:03:48 -05:00
zstyle ':prezto:module:git:info:remote' format ""
zstyle ':prezto:module:git:info:action' format "${yellow} %s"
zstyle ':prezto:module:git:info:position' format "${red} %p"
2013-05-22 17:07:24 -05:00
# Git commit SHA (in order in which it will appear in the prompt)
2013-08-20 16:33:12 -05:00
zstyle ':prezto:module:git:info:commit' format "${yellow} %.7c"
# zstyle ':prezto:module:git:info:commit' format "${color_prompt} ➤ ${yellow}%.7c"
2013-05-22 17:07:24 -05:00
# Git remote status (in order in which it will appear in the prompt)
2013-06-18 16:03:48 -05:00
zstyle ':prezto:module:git:info:behind' format "${magenta} ⬇ "
zstyle ':prezto:module:git:info:ahead' format "${magenta} ⬆ "
zstyle ':prezto:module:git:info:diverged' format "${magenta} ⥮"
zstyle ':prezto:module:git:info:stashed' format "${cyan} ✭"
2013-05-22 17:07:24 -05:00
# Git local status (in order in which it will appear in the prompt)
zstyle ':prezto:module:git:info:clean' format ""
2013-08-20 16:33:12 -05:00
zstyle ':prezto:module:git:info:dirty' format "${color_prompt} |"
# zstyle ':prezto:module:git:info:dirty' format "${yellow} ⚡${color_prompt} |"
2013-05-22 17:07:24 -05:00
zstyle ':prezto:module:git:info:added' format "${green} ✚"
zstyle ':prezto:module:git:info:deleted' format "${red} ✗"
zstyle ':prezto:module:git:info:modified' format "${blue} ✱"
zstyle ':prezto:module:git:info:renamed' format "${magenta} ➜"
zstyle ':prezto:module:git:info:unmerged' format "${yellow} ═"
zstyle ':prezto:module:git:info:untracked' format "${white} ◼"
# Git prompt styles
zstyle ':prezto:module:git:info:keys' format \
2013-06-18 16:03:48 -05:00
'prompt_info' "%b" \
'rprompt' "[%R]" \
'local_status' "%C%D%a%d%m%r%U%u" \
'remote_status' "%B%A%S" \
'sha' "%c" \
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Report ruby version
2013-06-18 16:03:48 -05:00
# %v - ruby version
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
2013-06-21 00:47:05 -05:00
zstyle ':prezto:module:ruby:info:version' format "${yellow}ruby%v "
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Vim mode indicator
# —————————————————————————————————————————————————————————————————————
2013-06-21 00:47:05 -05:00
zstyle ':prezto:module:editor:info:keymap:primary' format "${red}❱${color_prompt}❱❱ "
zstyle ':prezto:module:editor:info:keymap:alternate' format "${red}❰${color_prompt}❰❰ "
2013-06-18 16:03:48 -05:00
# zstyle ':prezto:module:editor:info:keymap:primary:insert' format "${red}I "
2013-05-22 17:07:24 -05:00
zstyle ':prezto:module:editor:info:keymap:primary:overwrite' format "${red}♺ "
2013-06-18 16:03:48 -05:00
zstyle ':prezto:module:editor:info:completing' format "${red}..."
2013-06-21 00:47:05 -05:00
2013-07-12 00:16:21 -05:00
# —————————————————————————————————————————————————————————————————————
# See if we can use extended characters to look nicer
# —————————————————————————————————————————————————————————————————————
typeset -A altchar
set -A altchar ${(s..)terminfo[acsc]}
altchar_enable="%{$terminfo[enacs]%}"
altchar_enter="%{$terminfo[smacs]%}"
altchar_leave="%{$terminfo[rmacs]%}"
altchar_padding=${altchar[q]:--}
altchar_upper_left_corner=%{$terminfo[smacs]%}${altchar[l]:--}${altchar[q]:--}%{$terminfo[rmacs]%}
altchar_lower_left_corner=%{$terminfo[smacs]%}${altchar[m]:--}${altchar[q]:--}%{$terminfo[rmacs]%}
altchar_upper_right_corner=%{$terminfo[smacs]%}${altchar[q]:--}${altchar[k]:--}%{$terminfo[rmacs]%}
altchar_lower_right_corner=%{$terminfo[smacs]%}${altchar[q]:--}${altchar[j]:--}%{$terminfo[rmacs]%}
# altchar_padding=${altchar[q]:-─}
# altchar_upper_left_corner=%{$terminfo[smacs]%}${altchar[l]:-╭}${altchar[q]:-─}%{$terminfo[rmacs]%}
# altchar_lower_left_corner=%{$terminfo[smacs]%}${altchar[m]:-╰}${altchar[q]:-─}%{$terminfo[rmacs]%}
# altchar_upper_right_corner=%{$terminfo[smacs]%}${altchar[q]:-─}${altchar[k]:-┐}%{$terminfo[rmacs]%}
# altchar_lower_right_corner=%{$terminfo[smacs]%}${altchar[q]:-─}${altchar[j]:-┘}%{$terminfo[rmacs]%}
2013-05-22 17:07:24 -05:00
# —————————————————————————————————————————————————————————————————————
# Finally! the PROMPT...
# - add %E to beginning of PROMPT to clear screen after every command
# —————————————————————————————————————————————————————————————————————
2013-06-18 16:03:48 -05:00
# Left PROMPT
2013-06-21 00:47:05 -05:00
if (( $SHLVL == 1 )); then
2013-07-12 00:16:21 -05:00
export PROMPT='${altchar_enable}${color_prompt}${altchar_lower_left_corner}${editor_info[keymap]}'
# export PROMPT='${altchar_enable}${color_prompt}${altchar_lower_left_corner}╰─${editor_info[keymap]}'
2013-06-21 00:47:05 -05:00
else
2013-07-12 00:16:21 -05:00
export PROMPT='${color_prompt}${altchar_lower_left_corner}( ${cyan}$SHLVL ${color_prompt}) ${editor_info[keymap]}'
2013-06-21 00:47:05 -05:00
fi
2013-06-18 16:03:48 -05:00
# Right PROMPT
2013-07-12 00:16:21 -05:00
export RPROMPT='${editor_info[alternate]}${editor_info[overwrite]}${return_code}${number_jobs}${line_number} ${current_time} ${color_prompt}❰${altchar_lower_right_corner}'
2013-06-18 16:03:48 -05:00
# Continuation PROMPT
export PROMPT2='${color_prompt}%_ ${editor_info[keymap]}'
# Selection PROMPT
export PROMPT3='${yellow}#? '
# Execution trace PROMPT
2013-06-21 00:47:05 -05:00
export PROMPT4='${blue}$0${color_prompt}@${yellow}%i+ '
2013-06-18 16:03:48 -05:00
# Backup scary root prompt (for default root prompt, i.e., usually bash)
# NOTE: different from zsh root prompt
export SUDO_PS1="\[\e[31;1;46m\][\u] \w \$\[\e[0m\] "
2013-05-22 17:07:24 -05:00
# Autocorrection PROMPT
2013-06-18 16:03:48 -05:00
export SPROMPT='
${color_prompt}Correct ${red}%R${color_prompt} to ${green}%r${color_prompt} ? [nyae] '
2013-05-22 17:07:24 -05:00
}
prompt_garrett_setup "$@"
2013-06-18 16:03:48 -05:00