Skip to content

Instantly share code, notes, and snippets.

@ceuk
Last active February 19, 2021 17:54
Show Gist options
  • Save ceuk/470b2ca785ca6f53cdcc3556b6d0afb4 to your computer and use it in GitHub Desktop.
Save ceuk/470b2ca785ca6f53cdcc3556b6d0afb4 to your computer and use it in GitHub Desktop.
Bash $ps1
#!/bin/bash
# Helper functions for color prompts
# You can specify common colors by name (see case
# statement below), 8-bit colors by decimal value,
# and (where available) TrueColor 24-bit colors
# as semicolon delimited decimals.
#
# With no arguments, resets the color to default.
#
# The second argument can set formatting, such as bold,
# dim, and invert. Use default as the color to just
# apply formatting.
#
# http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
# http://misc.flogisoft.com/bash/tip_colors_and_formatting
# http://unix.stackexchange.com/a/124409/19157
# https://gist.github.com/XVilka/8346728
function color() {
local color format code attr
color=$(echo "$1" | tr '[:upper:]' '[:lower:]')
format=$(echo "$2" | tr '[:upper:]' '[:lower:]')
case ${color//;/,} in # case doesn't seem to match semicolons
black) code=30 ;;
dgrey) code=90 ;;
red) code=31 ;;
lred) code=91 ;;
green) code=32 ;;
lgreen) code=92 ;;
yellow) code=33 ;;
lyellow) code=93 ;;
blue) code=34 ;;
lblue) code=94 ;;
purple) code=35 ;;
lpurple) code=95 ;;
cyan) code=36 ;;
lcyan) code=96 ;;
grey|lgrey) code=37 ;;
white) code=97 ;;
d|default) code=39 ;;
*[0-9],*) code="38;2;$color" ;;
*[0-9]*) code="38;5;$color" ;;
''|none) code=0 ;; # reset
*) echo "Invalid color $1" >&2 && return 1 ;;
esac
# TODO support multiple formattings, like BOLD UNDERLINE
case $format in
bold|bright) attr=1 ;;
dim) attr=2 ;;
italic) attr=3 ;; # limited support
underline) attr=4 ;;
blink) attr=5 ;; # you monster
reverse) attr=7 ;;
hide|hidden) attr=8 ;;
strike) attr=9 ;; # limited support
'') : ;; # no formatting
*) echo "Invalid format $2" >&2 && return 1 ;;
esac
printf '\033[%s%sm' "${attr:+$attr;}" "${code}"
}
# Wraps the color function in escaped square brackets,
# which is necessary in prompts (PS1, etc.) to tell
# bash the escape characters are non-printing.
function pcolor() {
# TODO \001...\002 doesn't appear to work on Ubuntu
#printf '\001%s\002' "$(color "$@")"
printf '\[%s\]' "$(color "$@")"
}
export -f color
export -f pcolor
# get current branch in git repo
function parse_git_branch() {
BRANCH=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ ! "${BRANCH}" == "" ]
then
STAT=$(parse_git_dirty)
echo "  ${BRANCH}${STAT}"
else
echo ""
fi
}
# get current status of git repo
function parse_git_dirty {
status=$(git status 2>&1 | tee)
dirty=$(echo -n "${status}" 2> /dev/null | grep "modified:" &> /dev/null; echo "$?")
up_to_date=$(echo -n "${status}" 2> /dev/null | grep "working tree clean" &> /dev/null; echo "$?")
behind=$(echo -n "${status}" 2> /dev/null | grep "Your branch is behind" &> /dev/null; echo "$?")
ahead=$(echo -n "${status}" 2> /dev/null | grep "Your branch is ahead of" &> /dev/null; echo "$?")
parts=''
if [ "${dirty}" == "0" ]; then
parts="${parts}*"
fi
if [ "${behind}" == "0" ]; then
parts="${parts} $(color 'BLUE')$(color)"
fi
if [ "${ahead}" == "0" ]; then
parts="${parts} $(color 'BLUE')$(color)"
fi
#if [ "${up_to_date}" == "0" ]; then
#parts="${parts} "
#fi
if [ ! "${parts}" == "" ]; then
echo -e "${parts}"
else
echo ""
fi
}
updateps1() {
local exit_code=$?
local has_jobs=$(jobs | wc -l)
ps1sub() {
local chevron_color=''
if [ "$exit_code" == "0" ]; then
if (( $has_jobs > 0 )); then
chevron_color='PURPLE'
else
chevron_color='D'
fi
else
chevron_color='RED'
fi
printf "$(pcolor 'LCYAN')\w$(pcolor 'DGREY')\`parse_git_branch\`\\n$(pcolor $chevron_color)❯$(pcolor) "
}
PS1="$(ps1sub)"
}
PROMPT_COMMAND='updateps1'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment