Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
# shellcheck shell=bash
# Customize bash prompt
# lolcat reference: http://apple.stackexchange.com/a/266112/216733
# If dynamic can use literal control characters. Otherwise,
# must use PS1 escapes or else line wrap issue.
PROMPT_COMMAND="__prompt_command${PROMPT_COMMAND:+"; $PROMPT_COMMAND"}"
PS1_COLORIZE_COMMAND='__ps1_lolcat'
# shellcheck disable=SC2034
PS1_DEBUG_COMMAND='__ps1_debug'
PS1_DEBUG='false'
__prompt_command() {
# Save last exit code
PS1_exit=$?
if [[ "$PS1_DEBUG" = 'true' ]]; then
if [[ "$PS1" = "$PS1_DEBUG_DISABLED" ]]; then
PS1=$PS1_DEBUG_ENABLED
fi
else
if [[ "$PS1" = "$PS1_DEBUG_ENABLED" ]]; then
PS1=$PS1_DEBUG_DISABLED
fi
fi
}
ps1_set_debug_mode() {
if [[ "$PS1_DEBUG" = 'true' ]]; then
PS1=$PS1_DEBUG_ENABLED
else
PS1=$PS1_DEBUG_DISABLED
fi
}
TERM_DEFAULT=$(tput sgr0)
TERM_RED=$(tput setaf 1)
TERM_GREEN=$(tput setaf 2)
TERM_BLUE=$(tput setaf 4)
ESC=$'\033'
SOH=$'\001'
STX=$'\002'
PS1_DEFAULT_LITERAL=$SOH$TERM_DEFAULT$STX
PS1_RED_LITERAL=$SOH$TERM_RED$STX
PS1_GREEN_LITERAL=$SOH$TERM_GREEN$STX
PS1_BLUE_LITERAL=$SOH$TERM_BLUE$STX
PS1_DEFAULT_ESCAPED='\['$TERM_DEFAULT'\]'
PS1_RED_ESCAPED='\['$TERM_RED'\]'
PS1_GREEN_ESCAPED='\['$TERM_GREEN'\]'
# Caveat:
# to have a literal '\' or '"' work in both $PS1_DEBUG_DISABLED and
# $PS1_DEBUG_ENABLED, '\' must be represented with '\\\\' and
# '"' must be represented with '\\"' or '\"' to have the proper amount of
# escaping in both modes. PS1 seems to have an initial interpret phase where
# it strips off one level of backslashes, then an echo phase where it strips
# off the second level so '\\\\' =interpret> '\\' =echo> '\'
# '\\"' =interpret> '\"' =echo> '"'
# The following is a bit trickier. Normally, echo would treat the double quote
# as starting a string. PS1 seems to treat it as a literal when echoing. As
# a result, '\\"' is preferred over '\"' as it is easier to understand what is
# happening.
# '\"' =interpret> 'literal(")' =echo> '"'
# In $PS1_DEBUG_ENABLED, the interpret phase is still run by PS1. The echo
# phase is emulated by wrapping $PS1 in double quotes: ...<<<"'PS1'"...
unset PS1
PS1_COLORLESS=$(sed 's/[[:space:]]*$//' <<<"${PS1:-\h:\W \u\\$}")
PS1_SPACING=' '
PS1=''
PS1_HISTORY_NUMBER='\!)'
PS1+='$(eval "$PS1_COLORIZE_COMMAND" <<<"'$PS1_HISTORY_NUMBER'")'
PS1+=$PS1_SPACING
# Rule is to use PS1_{COLOR}_ESCAPED if the escape sequence appears in PS1, but
# use PS1_{COLOR}_LITERAL if it doesn't e.g. it's inside a function.
PS1+='['
PS1+='$('
PS1+='if ((PS1_exit == 0)); then '
PS1+="echo '$PS1_GREEN_ESCAPED'; "
PS1+='else '
PS1+="echo '$PS1_RED_ESCAPED'; fi"
PS1+=')'
PS1+='$PS1_exit'
PS1+=$PS1_DEFAULT_ESCAPED
PS1+=']'
PS1+=$PS1_SPACING
PS1+='$(eval "$PS1_COLORIZE_COMMAND" <<<"'$PS1_COLORLESS'")'
PS1+=$PS1_SPACING
PS1_DEBUG_DISABLED=$PS1
# wrap PS1 for debugging
# shellcheck disable=SC2016
PS1_DEBUG_ENABLED='$(eval "$PS1_DEBUG_COMMAND" <<<"'$PS1'")'
__ps1_remove_newline() {
tr -d '\n'
}
__ps1_color_wrap_non_printing() {
local REGEX=$ESC'\[[[:digit:];]*m'
local REPLACE=$SOH'&'$STX
sed "s/$REGEX/$REPLACE/g"
}
__ps1_lolcat_ruby() {
rbenv exec lolcat -f -F 6 -p 25 | __ps1_color_wrap_non_printing
}
__ps1_lolcat_python() {
pyenv exec lolcat -f -F 6 -p 25 | __ps1_remove_newline \
| __ps1_color_wrap_non_printing
}
__ps1_lolcat() {
lolcat-c -f -h 0.8 | __ps1_remove_newline | __ps1_color_wrap_non_printing
}
# long colored prompt text that go over a line have a line wrap issue.
# Problem occurs with literal and PS1 escaped control characters. Tried
# escaping each individual character with perl at
# "$SCRIPTS_DIR"'/ps1_colorize_debug.pl' but still doesn't work.
# can't colorize debug literal text with sed because it does not have the
# following:
# non-greedy quantifiers to do \^B\(.*?\)\^A if running a second sed to
# consume \^B and \^A again.
# lookahead to do \(.*?)\(?=\^A) which wouldn't require a second sed because
# \^A is is looked for but not consumed.
# can use perl regex if want to colorize debug literal text.
# sed also doesn't have non capturing groups so groups are offset.
__ps1_colorize_debug() {
local SOH_REGEX='(\^A)'
local COLOR_CODE_REGEX='((\^\[\(B)?\^\[\[[[:digit:];]*m)'
local STX_REGEX='(\^B)'
local REGEX=$SOH_REGEX$COLOR_CODE_REGEX$STX_REGEX
local SOH_REPLACE=$PS1_RED_LITERAL'\1'$PS1_DEFAULT_LITERAL
local COLOR_CODE_REPLACE=$PS1_BLUE_LITERAL'\2'$PS1_DEFAULT_LITERAL
local STX_REPLACE=$PS1_GREEN_LITERAL'\4'$PS1_DEFAULT_LITERAL
local REPLACE=$SOH_REPLACE$COLOR_CODE_REPLACE$STX_REPLACE
sed -E "s/$REGEX/$REPLACE/g"
}
__ps1_debug() {
cat -v | __ps1_colorize_debug
}
__ps1_debug_sed() {
sed -e 's/'$ESC'/[ESC]/g' -e 's/'$SOH'/[SOH]/g' -e 's/'$STX'/[STX]/g'
}