# Declare and fill an associative array providing ANSI colors enclosed between
# \[ and \], as per the "PROMPTING" section of man bash:
function declare_colors {
local ci cj cn
declare -g -A c
c['normal']='\[\e[0m\]'
for cn in {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do
c["${cn}"]='\[\e['"${ci:=0};${cj:=30}"'m\]'
((++cj,(cj==38)?(cj=30,++ci):1))
done
}
function disable_colors {
local cn
declare -g -A c
for cn in normal {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do
c["${cn}"]=''
done
}
# Generate the PS1 variable; doing that in a function allows to reflect almost
# anything in the prompt.
function generate_ps1 {
# Save the return code value (rcv)
local rcv=$?
# Color for brackets and braces
local bc="${c['red']}"
# Pick the return code color (rcc)
local rcc='bright_green'
[ $rcv -ne 0 ] && rcc='bright_red'
local rc dstamp tstamp user host cwdir es
printf -v rc "%s[%s${rcv}%s]" "${bc}" "${c[${rcc}]}" "${bc}"
printf -v tstamp '[%s\\t%s]' "${c['bright_yellow']}" "${bc}"
printf -v user '[%s\\u%s]' "${c['cyan']}" "${bc}"
printf -v host '{%s\\h%s}' "${c['cyan']}" "${bc}"
printf -v cwdir '%s\w%s ' "${c['green']}" "${c['normal']}"
printf -v es '%s\$%s ' "${c['red']}" "${c['normal']}"
if [ "${PS1_DISPLAY_DATE}" ]; then
printf -v dstamp '[%s\\D{%%F}%s]' "${c['bright_yellow']}" "${bc}"
fi
PS1="${rc}${dstamp}${tstamp}${user}${host}${cwdir}${es}"
# Also set PS2 and PS4:
PS2="${c['bright_green']}"
PS4="+ ${c['cyan']}[trace]${c['normal']} "
# It makes sense to export PS4 (so that e.g. "bash foobar.sh" benefit from
# it):
export PS4
}
# Provide a helper function to swiftly enable or disable the date in the
# prompt:
function ps1_toggle_date {
if [ "${PS1_DISPLAY_DATE}" ]; then
unset PS1_DISPLAY_DATE
else
PS1_DISPLAY_DATE='yes'
fi
}
# Provide a helper function to swiftly enable or disable colors in the
# prompt:
function ps1_toggle_colors {
if [ "${PS1_USE_COLORS}" ]; then
unset PS1_USE_COLORS
disable_colors
else
declare_colors
PS1_USE_COLORS='yes'
fi
}
# Provide a helper function to swiftly reduce the prompt to '$ ' -- this is
# useful e.g. for documentation purposes, when one wants to run a few commands
# and copy the whole terminal output without the prompt (which usually reflects
# undesired details such as user and hostname):
function ps1_toggle_prompt {
local min_prompt='\$ '
if [ "${PS1}" == "${min_prompt}" ]; then
PROMPT_COMMAND='generate_ps1'
generate_ps1
else
unset PROMPT_COMMAND
PS1="${min_prompt}"
fi
}
# By default, use colors but do not display the date:
ps1_toggle_colors
#ps1_toggle_date
# Instruct bash to regenerate PS1 before printing the prompt:
PROMPT_COMMAND='generate_ps1'
# Generate PS1 at least once:
generate_ps1