Skip to content

Instantly share code, notes, and snippets.

@nebtrx
Created November 21, 2017 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nebtrx/e9d8fb0d3e6d12d14200a230361d9636 to your computer and use it in GitHub Desktop.
Save nebtrx/e9d8fb0d3e6d12d14200a230361d9636 to your computer and use it in GitHub Desktop.
modified-garret-theme
#!/usr/bin/env zsh
#
# Garrett Zsh Theme for Prezto
# Created with modified code by Chauncey Garrett - @chauncey_io
#
# http://chauncey.io/projects/zsh-prompt-garrett/
#
# A prompt with the information you need the moment you need it.
#
# 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 truncated present working directory
# - Report return codes other than 0
# - Report local time
# - Report the terminal line number
# - Report git status, git remote status, git prompt info and git SHA information
# - Indicate vi-mode
# - Notifications for commands taking longer than n time
#
# Features may be disabled and rearranged as desired by using the corresponding tokens.
#
# Load dependencies.
pmodload 'helper'
zmodload -i zsh/datetime
# Prompt configuration help.
# TODO not even remotely finished...
# function prompt_garrett_help() {
# cat <<'EOF'
# This prompt is configurable via styles:
# Context: :prompt:garrett
# Colors (red green yellow blue magenta cyan white grey):
# prompt_garrett_color_user The color for user@host. Defaults to 'green'
# root_color The color for the hostname for root. Defaults to 'red'
# prompt_garrett_color_prompt The color for everything else. Defaults to ''
# Path (path type - possible values):
# ratio Use COLUMNS/ratio to clip the path. Default.
# fixed Use a fixed maximum length.
# subdir Clip by number of subdirectories.
# full Show the full path
# 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 subdirectories to show for the 'subdir' path style. Defaults to 3.
# You can set styles in the current terminal to test things out, values will be updated.
# EOF
# }
# Display a preview of the prompt.
# TODO not ready.
# function prompt_garrett_preview {
# Display the passed in parameters.
# if (( $> 0 )); then
# prompt_preview_theme 'garrett' "$@"
# Display the default settings.
# else
# prompt_preview_theme 'garrett' red green blue
# fi
# }
# Notify of command completion after n seconds has passed.
function prompt_garrett_precmd_notification {
# Trigger a notification after n seconds have elapsed.
prompt_garrett_delay_after_notification=2
# Determine time elapsed.
prompt_garrett_precmd_time_elapsed_start=${prompt_garrett_preexec_time:-$EPOCHSECONDS}
prompt_garrett_precmd_time_elapsed_stop=$EPOCHSECONDS
let prompt_garrett_precmd_time_elapsed=$prompt_garrett_precmd_time_elapsed_stop-$prompt_garrett_precmd_time_elapsed_start
# n seconds have passed, so notify!
if [ $prompt_garrett_precmd_time_elapsed -gt $prompt_garrett_delay_after_notification ]; then
# Notify via tput while on ssh.
if [[ -n "$SSH_CLIENT" || -n "$SSH2_CLIENT" ]]; then
tput bel
# Use local notifications.
else
# On OS X, notify with terminal-notifier.
if [[ "$OSTYPE" == darwin* ]] && (( $+commands[terminal-notifier] )); then
# Wrap with reattach-to-usernamespace to allow to work in TMUX.
if (( $+commands[reattach-to-user-namespace] )); then
reattach-to-user-namespace -l terminal-notifier \
-title "${prompt_garrett_preexec_cmd:-Unknown command}" \
-message "Required $prompt_garrett_precmd_time_elapsed s" \
-sound Tink
else
terminal-notifier \
-title "${prompt_garrett_preexec_cmd:-Unknown command}" \
-message "Required $prompt_garrett_precmd_time_elapsed s" \
-sound Tink
fi
# On linux, notify with notify-send.
elif [[ "$OSTYPE" == linux-gnu ]] && (( $+commands[notify-send] )); then
notify-send \
"${prompt_garrett_preexec_cmd:-Unknown command}" \
"Required $prompt_garrett_precmd_time_elapsed s"
# Notify via tput.
else
tput bel
fi
fi
fi
}
# Handle clearing the screen with ^L.
function prompt_garrett_clear_screen() {
# Enable output to terminal.
zle -I
clear
prompt_garrett_preprompt_render
}
# A function executed whenever the directory is changed.
function prompt_garrett_chpwd {
# List the contents of the new directory.
if is-callable 'dircolors'; then
# GNU flavor ls.
if zstyle -t ':prezto:module:utility:ls' color; then
ls --group-directories-first --color=auto
else
ls -F
fi
else
# BSD flavor ls.
if zstyle -t ':prezto:module:utility:ls' color; then
ls -G
else
ls -F
fi
fi
}
# Functions called before command execution.
function prompt_garrett_preexec {
# Define timer and command for notification.
export prompt_garrett_preexec_time=$EPOCHSECONDS
export prompt_garrett_preexec_cmd="\$ $1"
# Ensure terminal code isn't colored from prompt.
print -n "$reset_color"
}
# Functions called before each prompt is displayed.
function prompt_garrett_precmd {
setopt LOCAL_OPTIONS
unsetopt XTRACE KSH_ARRAYS
# Show number of background jobs.
prompt_garrett_number_jobs="%(1j.${prompt_garrett_color_prompt}J:${cyan}%j .)"
# Format PWD.
prompt_garrett_pwd="${prompt_garrett_color_pwd}$(prompt-pwd)"
# Trigger a notification after x time has elapsed.
eval prompt_garrett_precmd_notification
# Get Ruby info.
if (( $+functions[ruby-info] )); then
ruby-info
fi
# Get Git repository info.
if (( $+functions[git-info] )); then
git-info
fi
prompt_garrett_preprompt_render
}
# Add a line to prompt for visibility.
function prompt_garrett_preprompt_render() {
# Determine the width.
local prompt_garrett_width_terminal
(( prompt_garrett_width_terminal= ${COLUMNS} - 1 ))
# Determine the length needed for prompt_garrett_space.
# NOTE: Be sure not to include the ${(e)prompt_garrett_space} portion or it won't work.
local prompt_line1="${prompt_garrett_upper_left_corner}( ${prompt_garrett_pwd}${git_info[remote_status]}${git_info[prompt_info]}${git_info[local_status]}${git_info[sha]} )( ${ruby_info[version]}${prompt_garrett_location} )${prompt_garrett_upper_right_corner}"
local zero='%([BSUbfksu]|([FB]|){*})'
local prompt_garrett_width_line1=${#${(S%%)prompt_line1//$~zero/}}
# Calculate the padding.
local prompt_garrett_space_padding
(( prompt_garrett_space_padding= ${prompt_garrett_width_terminal} - ${prompt_garrett_width_line1} ))
# Add the correct number of characters.
local prompt_space_character="${prompt_garrett_altchar_padding}"
eval prompt_garrett_space="${prompt_garrett_color_prompt}\${(l.${prompt_garrett_space_padding}..${prompt_space_character}.)}"
# Newline + Prompt line 1 (set above PROMPT, below).
print -P '\n${prompt_garrett_altchar_enable}${prompt_garrett_color_prompt}${prompt_garrett_upper_left_corner}( ${prompt_garrett_pwd}${git_info[remote_status]}${git_info[prompt_info]}${git_info[local_status]}${git_info[sha]} ${prompt_garrett_color_prompt})${prompt_garrett_altchar_enter}${(e)prompt_garrett_space}${prompt_garrett_altchar_leave}( ${ruby_info[version]}${prompt_garrett_location}${prompt_garrett_color_prompt} )${prompt_garrett_upper_right_corner}'
}
# Configure the prompt.
function prompt_garrett_setup {
# Load necessary modules.
setopt LOCAL_OPTIONS
unsetopt XTRACE KSH_ARRAYS
prompt_opts=(cr percent sp subst)
# Add hooks for calling preexec, precmd & chpwd.
autoload -Uz add-zsh-hook
add-zsh-hook preexec prompt_garrett_preexec
add-zsh-hook precmd prompt_garrett_precmd
add-zsh-hook chpwd prompt_garrett_chpwd
#
# Colors
#
# Alias the colors.
[[ -z $(functions colors) ]] && autoload -U colors && colors
for color in red green yellow blue magenta cyan white grey; do
# Normal colors.
eval $color='%F{${(L)color}}'
# Bold colors.
eval ${color}_bold='%B{${(L)color}}'
done
# Color scheme.
eval prompt_garrett_color_pwd=\$\{${2:-'${blue}'}\}
# eval prompt_garrett_color_pwd=${2:-'${blue}'}
# eval prompt_garrett_color_line_number=${5:-'${magenta}'}
# eval prompt_garrett_color_time=${6:-'${green}'}
# eval prompt_garrett_color_git_branch=${7:-'${green}'}
# eval prompt_garrett_color_git_sha=${8:-'${yellow}'}
# eval prompt_garrett_color_ruby_version=${8:-'${yellow}'}
# Override the default clear-screen so that ^L displays the prompt in its
# entirety.
if [[ $widgets[clear-screen] == 'builtin' ]]; then
zle -N clear-screen prompt_garrett_clear_screen
fi
#
# Determine prompt, user and host colors.
#
# Root user.
if [[ "$EUID" = "0" ]] || [[ "$USER" = 'root' ]]; then
# Set colors.
eval prompt_garrett_color_user=${3:-'${red}'}
eval prompt_garrett_color_host=${3:-'${red}'}
eval prompt_garrett_color_prompt=${3:-'${red}'}
# Set style.
eval prompt_garrett_user='%S${prompt_garrett_color_user}%n%s'
eval prompt_garrett_host='${prompt_garrett_color_host}%m' # hostname up to first . (dot) (use %M for full hostname)
eval prompt_garrett_location='${prompt_garrett_user}${cyan}@${prompt_garrett_host}' # user@host.name
# On SSH.
elif [[ -n "$SSH_CLIENT" || -n "$SSH2_CLIENT" ]]; then
# Set colors.
eval prompt_garrett_color_user=${3:-'${green}'}
eval prompt_garrett_color_host=${3:-'${yellow}'}
eval prompt_garrett_color_prompt=${3:-'${yellow}'}
# Set style.
eval prompt_garrett_user='%S${prompt_garrett_color_user}%n%s'
eval prompt_garrett_host='${prompt_garrett_color_host}%m' # hostname up to first . (dot) (use %M for full hostname)
eval prompt_garrett_location='${prompt_garrett_user}${cyan}@${prompt_garrett_host}' # user@host.name
# Normal user.
else
# Set colors.
eval prompt_garrett_color_user=${1:-'${green}'}
eval prompt_garrett_color_host=${1:-'${green}'}
eval prompt_garrett_color_prompt=${1:-'${grey}'}
# Set style.
eval prompt_garrett_user=''
eval prompt_garrett_host='${prompt_garrett_color_host}%m' # hostname up to first . (dot) (use %M for full hostname)
eval prompt_garrett_location='${prompt_garrett_user}${cyan}@${prompt_garrett_host}' # user@host.name
fi
#
# Report return code.
#
eval prompt_garrett_return_code='%(?..${red}%? ⏎ ) '
#
# Report local time.
#
eval prompt_garrett_current_time='${green}%T' # 24 hour time format
# eval prompt_garrett_current_time='${green}%*' # 24 hour time format, second precise
# eval prompt_garrett_current_time='${green}%t' # AM/PM time format
# Keep the time updated.
# TODO: Figure out a better way to do this.
# function 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
#
# Report terminal line number.
#
eval prompt_garrett_line_number='${green}+${magenta}%!'
#
# Report git info.
# NOTE: Listed in order in which the information will appear in the prompt.
#
# Git verbose data (commit counts, etc.)
# zstyle ':prezto:module:git:info' verbose 'yes'
# Git prompt info.
zstyle ':prezto:module:git:info:branch' format "${cyan} λ${prompt_garrett_color_prompt}:${green}%b"
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"
# Git commit SHA.
zstyle ':prezto:module:git:info:commit' format "${yellow} %.7c"
# Git remote status.
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} ✭"
# Git local status.
zstyle ':prezto:module:git:info:clean' format ""
zstyle ':prezto:module:git:info:dirty' format "${prompt_garrett_color_prompt} |"
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 \
'prompt_info' "%b" \
'rprompt' "%R" \
'local_status' "%C%D%a%d%m%r%U%u" \
'remote_status' "%B%A%S" \
'sha' "%c" \
#
# Report Ruby version.
# %v | ruby version
#
zstyle ':prezto:module:ruby:info:version' format "${yellow}ruby:%v "
#
# Command line editor info.
#
# Base style.
zstyle ':prezto:module:editor:info:keymap:primary' format "${red}❯%(?.${prompt_garrett_color_prompt}.${red})❯❯ "
# Vim insert mode.
# zstyle ':prezto:module:editor:info:keymap:primary:insert' format "${red}I "
# Vim overwrite mode.
zstyle ':prezto:module:editor:info:keymap:primary:overwrite' format "${red}♺ "
# Vim normal (command) mode.
zstyle ':prezto:module:editor:info:keymap:alternate' format "${red}❮%(?.${prompt_garrett_color_prompt}.${red})❮❮ "
# Tab completion mode.
zstyle ':prezto:module:editor:info:completing' format "${red}..."
#
# Use the extended character set, if available.
#
typeset -A altchar
set -A altchar ${(s..)terminfo[acsc]}
prompt_garrett_altchar_enable="%{$terminfo[enacs]%}"
prompt_garrett_altchar_enter="%{$terminfo[smacs]%}"
prompt_garrett_altchar_leave="%{$terminfo[rmacs]%}"
# Character used to draw line.
prompt_garrett_altchar_padding=${altchar[q]:--}
# Upper left corner: ┌
prompt_garrett_upper_left_corner=${prompt_garrett_altchar_enter}${altchar[l]:--}${altchar[q]:--}${prompt_garrett_altchar_leave}
# Lower left corner: └
prompt_garrett_lower_left_corner=${prompt_garrett_altchar_enter}${altchar[m]:--}${altchar[q]:--}${prompt_garrett_altchar_leave}
# Upper right corner: ┐
prompt_garrett_upper_right_corner=${prompt_garrett_altchar_enter}${altchar[q]:--}${altchar[k]:--}${prompt_garrett_altchar_leave}
# Upper right corner: ┘
prompt_garrett_lower_right_corner=${prompt_garrett_altchar_enter}${altchar[q]:--}${altchar[j]:--}${prompt_garrett_altchar_leave}
#
# Print out the prompt.
#
# Left prompt; base shell level.
if (( $SHLVL == 1 )); then
export PROMPT='${prompt_garrett_altchar_enable}${prompt_garrett_color_prompt}${prompt_garrett_lower_left_corner}${editor_info[keymap]}'
# Left prompt; nested shell level.
else
export PROMPT='${prompt_garrett_color_prompt}${prompt_garrett_lower_left_corner}( ${cyan}$SHLVL ${prompt_garrett_color_prompt}) ${editor_info[keymap]}'
fi
# Right prompt.
export RPROMPT='${editor_info[alternate]}${editor_info[overwrite]}${prompt_garrett_return_code}${prompt_garrett_number_jobs}${prompt_garrett_line_number} ${prompt_garrett_current_time} %(?.${prompt_garrett_color_prompt}.${red})❮${prompt_garrett_color_prompt}${prompt_garrett_lower_right_corner}'
# Continuation prompt.
export PROMPT2='(%_) ${editor_info[keymap]}'
# Selection prompt.
export PROMPT3='
(?) ${editor_info[keymap]}'
# Execution trace prompt.
export PROMPT4='${yellow}+${blue}%N ${green}@${magenta}%i ${reset_color}'
# Autocorrection prompt.
export SPROMPT='
${prompt_garrett_color_prompt}Correct ${red}%R${prompt_garrett_color_prompt} to ${green}%r${prompt_garrett_color_prompt} ? [nyae] '
# Backup root prompt for Bash.
export SUDO_PS1="\[\e[31;1;46m\][\u] \w \$\[\e[0m\] "
}
prompt_garrett_setup "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment