Skip to content

Instantly share code, notes, and snippets.

@austinbeam
Last active August 29, 2015 13:59
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 austinbeam/10930268 to your computer and use it in GitHub Desktop.
Save austinbeam/10930268 to your computer and use it in GitHub Desktop.
Bash Prompt Config File
# ~/.bash_prompt
# vi: ft=sh
# Austin Beam
# Include the bash_colors if it's installed
[ -f ~/.bash_colors ] && . ~/.bash_colors
# Include the git_aware functionality if it's installed
[ -f ~/.bash_git_aware ] && . ~/.bash_git_aware
# Include the cc_aware (ClearCase) functionality if it's installed
[ -f ~/.bash_cc_aware ] && . ~/.bash_cc_aware
# Configure the colors to be used in the prompt
_time_c="${PURPLE_FG}"
_load_c="${PURPLE_FG}"
_es_c="${COLOR_BOLD}${RED_FG}"
_exectime_c="${LIGHT_BLUE_FG}"
_user_c="${COLOR_RESET_BOLD}${BLUE_FG}"
_host_c="${GREEN_FG}"
_work_c="${CYAN_FG}"
_git_fast_c="${COLOR_BOLD}${BLUE_FG}"
_git_branch_c="${COLOR_BOLD}${GREEN_FG}"
_git_untracked_c="${COLOR_RESET_BOLD}${RED_FG}"
_p_number_c="${RED_FG}"
_p_user_c="${RED_FG}"
_reset_c="${COLOR_RESET}"
# These colors will be used with 'echo' so they need the escapes removed from
# beginning and end
if [ "${BASH_VERSINFO[0]}" -ge "4" -a \
\( "${BASH_VERSINFO[1]}" -ge "2" -o "${BASH_VERSINFO[0]}" -gt "4" \) ]; then
_exec_c="${LIGHT_BLUE_FG:2: -2}"
_exec_reset_c="${COLOR_RESET:2: -2}"
else
# Need to set these manually if the bash version is < 4.2. 4.2 introduced the
# concept of negative-indexed substrings as used above
_exec_c="\033[94m"
_exec_reset_c="\033[0m"
fi
# Check the exit status of the previous command
check_es() { es=$?; [ $es -ne 0 ] && _esout=" | ${es}" || unset _esout; }
# Get previous command execution time (wall time)
get_exectime()
{
if [ ! -z "$cmd_start_time" ]; then
local exectime=$(($(date +%s%N | cut -b1-13) - $cmd_start_time))
if [ "$last_exectime" == "$cmd_start_time" ]; then
unset _exectime
else
# Split the exec time into centiseconds, seconds, minutes, and hours
local csecs=$(printf "%02d" $((($exectime/10) % 100)))
local secs=$(printf "%02d" $((($exectime/1000) % 60)))
local mins=$(printf "%02d" $(($exectime/(1000*60) % 60)))
local hours=$(printf "%02d" $(($exectime/(1000*60*60) % 24)))
if [ "$secs" -eq "00" -a "$mins" -eq "00" -a "$hours" -eq "00" ]; then
_exectime=" | 0.${csecs}"
elif [ "$mins" -eq "00" -a "$hours" -eq "00" ]; then
_exectime=" | 0:${secs}.${csecs}"
elif [ "$hours" -eq "00" ]; then
_exectime=" | 0:${mins}:${secs}.${csecs}"
else
_exectime=" | ${hours}:${mins}:${secs}.${csecs}"
fi
last_exectime=$cmd_start_time
fi
fi
}
# Function to execute before prompt commands - print the command and save its
# start time. This is nice because it expands aliases and lets us know exactly
# what's being executed at any given time
pre_exec()
{
if [ "$BASH_COMMAND" != "trap - DEBUG" -a \
"$BASH_COMMAND" != "check_es" ]; then
# Echo each command prior to execution
echo -e "${_exec_c}$BASH_COMMAND${_exec_reset_c}"
# Save the command start time in milliseconds
cmd_start_time="$(date +%s%N | cut -b1-13)"
#cmd_start_time="${_time_c}$(date +%H:%M:%S).$(date +%N | cut -b1-2)"
fi
}
# Save the string (note: we don't want to execute this here, hence the '\$') for
# gathering the system load
_load=" | \$(cat /proc/loadavg | cut -d' ' -f 1,2,3 | tr -d "\n")"
# Set variables we'll use in the prompt
_w_title='\[\033]0;\u@\h: \w\007\]'
# Function to build our prompt
prompt-build()
{
local prompt_command=""
local ps1=""
# Commands before PS1 definition
[ -z "$_P_ES" ] \
|| prompt_command="check_es;"
# Always clear the DEBUG trap (or else it could get left on when we don't want
# it to be left on
prompt_command="${prompt_command} trap - DEBUG;"
[ -z "$_P_TIMER" ] \
|| prompt_command="${prompt_command} get_exectime;"
if [ ! -z "$_P_GITFULL" ]; then
prompt_command="${prompt_command} find_git_branch; git_dirty;"
elif [ ! -z "$_P_GITFAST" ]; then
prompt_command="${prompt_command} find_git_branch; quick_git_dirty;"
elif [ ! -z "$_P_GITFASTER" ]; then
prompt_command="${prompt_command} find_git_branch;"
fi
if [ ! -z "$_P_CLEARCASE" ]; then
prompt_command="${prompt_command} clearcase_view;"
fi
# PS1 definition
# Line 1
# Window title
# Add a hacky fix for Ubuntu virtual terminals, which don't properly handle the
# window title escape sequence. Make sure the virtual terminal is greater than
# or equal to 7.
if [ ! -z "$XDG_VTNR" ]; then
if [ $XDG_VTNR -ge 7 ]; then
[ -z "$_P_TITLE" ] || ps1="${ps1}${_w_title}${reset_c}"
fi
fi
# Time
[ -z "$_P_COLOR" ] || ps1="${ps1}${_time_c}"
[ -z "$_P_TIME" ] || ps1="${ps1}\t"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Load
[ -z "$_P_COLOR" ] || ps1="${ps1}${_load_c}"
[ -z "$_P_LOAD" ] || ps1="${ps1}\${_load}"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Execution timer
[ -z "$_P_COLOR" ] || ps1="${ps1}${_exectime_c}"
[ -z "$_P_TIMER" ] || ps1="${ps1}\${_exectime}"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Exit status
[ -z "$_P_COLOR" ] || ps1="${ps1}${_es_c}"
[ -z "$_P_ES" ] || ps1="${ps1}\${_esout}"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# New line if this is at least 3-line prompt
[ "$_P_LINES" -ge "3" ] && ps1="${ps1}\n"
# Line 2
# Username
[ -z "$_P_COLOR" ] || ps1="${ps1}${_user_c}"
[ -z "$_P_USER" ] || ps1="${ps1}\u"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Hostname
[ -z "$_P_COLOR" ] || ps1="${ps1}${_host_c}"
[ -z "$_P_HOST" ] || ps1="${ps1}@\h"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Working directory
[ -z "$_P_COLOR" ] || ps1="${ps1}${_work_c}"
[ -z "$_P_WORK" ] || ps1="${ps1} \w"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Git prompt support
# Only turn on the branch coloring if prompt color is enabled and either
# gitfull or gitfast is enabled (git_dirty_color overrides git_branch_c if
# the repository is dirty)
[ -z "$_P_COLOR" -o \( -z "$_P_GITFULL" -a -z "$_P_GITFAST" \) ] \
|| ps1="${ps1}${_git_branch_c}\${git_dirty_color}"
[ -z "$_P_GITFULL" -a -z "$_P_GITFAST" -a -z "$_P_GITFASTER" ] \
|| ps1="${ps1}\${git_branch}"
[ -z "$_P_GITFULL" -a -z "$_P_GITFAST" ] \
|| ps1="${ps1}\${git_dirty}"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Only turn on the git_untracked_color if prompt color is enabled and either
# gitfull or gitfast is enabled
[ -z "$_P_COLOR" -o \( -z "$_P_GITFULL" -a -z "$_P_GITFAST" \) ] \
|| ps1="${ps1}${_git_untracked_c}"
[ -z "$_P_GITFULL" ] || ps1="${ps1} \${git_untracked}"
[ -z "$_P_GITFAST" ] || ps1="${ps1} |"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Clearcase prompt support
[ -z "$_P_COLOR" -o -z "$_P_CLEARCASE" ] \
|| ps1="${ps1}\${_cc_c}"
[ -z "$_P_CLEARCASE" ] \
|| ps1="${ps1}\${_cc_root}"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# New line if this is at least a 2-line prompt
[ "$_P_LINES" -ge "2" ] && ps1="${ps1}\n"
# Line 3
# Prompt number
[ -z "$_P_COLOR" ] || ps1="${ps1}${_p_number_c}"
[ -z "$_P_NUMBER" ] || ps1="${ps1}\#"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# User type
[ -z "$_P_COLOR" ] || ps1="${ps1}${_p_user_c}"
[ -z "$_P_USRTYP" ] || ps1="${ps1}\$"
[ -z "$_P_COLOR" ] || ps1="${ps1}${_reset_c}"
# Space before prompt text (i.e. '$ ')
[ -z "$_P_SPACE" ] || ps1="${ps1} "
# Add PS1 to the prompt command
prompt_command="${prompt_command} export PS1=\"$ps1\";"
# Commands after PS1 definition
[ -z "$_P_TIMER" ] \
|| prompt_command="${prompt_command} trap 'pre_exec' DEBUG;"
export PROMPT_COMMAND="${prompt_command}"
}
# Reset all prompt features
prompt-reset()
{
_P_LINES=1
unset _P_COLOR \
_P_TITLE \
_P_TIME _P_LOAD _P_TIMER _P_ES \
_P_USER _P_HOST _P_WORK _P_GITFULL _P_GITFAST _P_GITFASTER \
_P_NUMBER _P_USRTYP _P_SPACE
}
# Full git prompt support (slowest, but provides the repo status and untracked
# file count)
prompt-full()
{
prompt-reset
_P_LINES=3
_P_COLOR=true; _P_TITLE=true;
_P_TIME=true; _P_LOAD=true; _P_TIMER=true; _P_ES=true
_P_USER=true; _P_HOST=true; _P_WORK=true; _P_GITFULL=true; _P_CLEARCASE=true
_P_NUMBER=true; _P_USRTYP=true; _P_SPACE=true
prompt-build
}
# Fast git prompt support (doesn't show untracked file count)
prompt-fast()
{
prompt-reset
_P_LINES=3
_P_COLOR=true; _P_TITLE=true;
_P_TIME=true; _P_LOAD=true; _P_TIMER=true; _P_ES=true
_P_USER=true; _P_HOST=true; _P_WORK=true; _P_GITFAST=true; _P_CLEARCASE=true
_P_NUMBER=true; _P_USRTYP=true; _P_SPACE=true
prompt-build
}
# Faster git prompt support (only shows branch name, no status or untracked file
# count)
prompt-faster()
{
prompt-reset
_P_LINES=3
_P_COLOR=true; _P_TITLE=true;
_P_TIME=true; _P_LOAD=true; _P_TIMER=true; _P_ES=true
_P_USER=true; _P_HOST=true; _P_WORK=true; _P_GITFASTER=true; _P_CLEARCASE=true
_P_NUMBER=true; _P_USRTYP=true; _P_SPACE=true;
prompt-build
}
# Disable git prompt support totally (fastest)
prompt-git-off()
{
unset _P_GITFULL _P_GITFAST _P_GITFASTER
prompt-build
}
prompt-color-off()
{
unset _P_COLOR
prompt-build
}
prompt-features()
{
[ -z "$_P_LINES" ] || echo -n "Lines: $_P_LINES "
[ -z "$_P_TITLE" ] || echo -n "Title "
[ -z "$_P_COLOR" ] || echo -n "Color "
[ -z "$_P_TIME" ] || echo -n "Time "
[ -z "$_P_LOAD" ] || echo -n "Load "
[ -z "$_P_TIMER" ] || echo -n "Timer "
[ -z "$_P_ES" ] || echo -n "ExitStatus "
[ -z "$_P_USER" ] || echo -n "Username "
[ -z "$_P_HOST" ] || echo -n "Hostname "
[ -z "$_P_WORK" ] || echo -n "WorkingDir "
[ -z "$_P_GITFULL" ] || echo -n "GitFull "
[ -z "$_P_GITFAST" ] || echo -n "GitFast "
[ -z "$_P_GITFASTER" ] || echo -n "GitFaster "
[ -z "$_P_NUMBER" ] || echo -n "CmdNumber "
[ -z "$_P_USRTYP" ] || echo -n "UserType "
[ -z "$_P_SPACE" ] || echo -n "Space "
echo
}
# Define aliases for even more basic prompts when needed
alias prompt-basic="export PROMPT_COMMAND=; export PS1='\t\n\u@\h \w\n\$ '"
alias prompt-min="export PROMPT_COMMAND=; export PS1='\$ '"
# Enable full git support for the prompt by default
prompt-full
@austinbeam
Copy link
Author

Needed to make a revision adding '.sh' as the extension for Gist to display this as a shell-formatted file (doesn't seem to like it when you manually configure the 'language' setting).

Enjoy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment