127 lines
4.0 KiB
Bash
127 lines
4.0 KiB
Bash
|
# 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_BOLD=$(tput bold) # I added this, as of now unused
|
||
|
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'\]'
|
||
|
|
||
|
# 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
|
||
|
# vvv - actually change PS1 here - vvv
|
||
|
PS1_COLORLESS=$(sed 's/[[:space:]]*$//' <<<"${PS1:-[\u@\h]:\w \\$}")
|
||
|
PS1_SPACING=' '
|
||
|
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"
|
||
|
}
|
||
|
|
||
|
# change lolcat arguments here
|
||
|
__ps1_lolcat() {
|
||
|
lolcat-c -f -h 1.4 | __ps1_remove_newline | __ps1_color_wrap_non_printing
|
||
|
}
|
||
|
PS1+='$(eval "$PS1_COLORIZE_COMMAND" <<<"'$PS1_COLORLESS'")'
|
||
|
PS1+=$PS1_SPACING
|
||
|
|
||
|
PS1_DEBUG_DISABLED=$PS1
|
||
|
# 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'
|
||
|
}
|
||
|
# wrap PS1 for debugging
|
||
|
# shellcheck disable=SC2016
|
||
|
PS1_DEBUG_ENABLED='$(eval "$PS1_DEBUG_COMMAND" <<<"'$PS1'")'
|