Skip to content

Instantly share code, notes, and snippets.

@nabrahamson
Forked from moshen/prompt.bash
Last active July 22, 2021 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nabrahamson/88285b07ce19fd22ec4ebf8368031f98 to your computer and use it in GitHub Desktop.
Save nabrahamson/88285b07ce19fd22ec4ebf8368031f98 to your computer and use it in GitHub Desktop.
A Fancy Bash Prompt
#!/bin/bash
#
# Fancy prompt
#
# Source this file in your .bashrc
#
# Configuration options:
#
# Set _prompt_config to an array of strings. Each string is in the
# format of: "function_name background_color foreground_color"
#
# The default _prompt_config is:
# _prompt_config=(
# "_prompt_seg_command_state 8 0"
# "_prompt_seg_hostname $_prompt_hostname_color 15"
# "_prompt_seg_dir 12 8"
# "_prompt_seg_git 5 7"
# )
#
# The functions are called in the order listed, and are passed in the
# name of a variable to assign text for the segment, and the last
# status code.
#
# If no text is written to the varible, then the segment is not
# displayed at all. Segments may also overwrite a variable called
# `seg` to modify their own function name or color codes.
#
# To create additional prompt segments, simply include a function that
# matches this signature and include it in the _prompt_config.
#
#
# Set POWERLINE_FONT=1 to enable, otherwise defaults to a basic prompt
#
# Setup git_ps1 options if you want to see them
# export GIT_PS1_SHOWDIRTYSTATE=1
# export GIT_PS1_SHOWSTASHSTATE=1
# export GIT_PS1_SHOWUNTRACKEDFILES=1
#
# Set _prompt_rainbow to an array of color indexes to cycle through
# otherwise, a default rainbow will be set.
#
# Set _prompt_rainbow_index to a starting color index of _prompt_rainbow
# otherwise, a random index will be used each time the prompt
# is initialized.
#
# Set _prompt_rainbow_pause=1 to keep the same color. Useful
# if you want to identify multiple windows/terms.
#
# Set _prompt_hostname_color to a valid 256 color code otherwise,
# one will be randomly set for you.
#
_prompt_hostname="$(perl -pe 's/\..+$//' <<<"$HOSTNAME")"
_prompt_rainbow_pause=""
if [ -e ~/.bash/git-prompt.sh ]
then source ~/.bash/git-prompt.sh
fi
function _prompt_set_arrow_char {
if [[ $POWERLINE_FONT ]]; then
__prompt_arrow_char=""
else
__prompt_arrow_char="▚"
fi
}
_prompt_set_arrow_char
if [[ -z $_prompt_rainbow ]]; then
_prompt_rainbow=( 154 154 154 184 184 214 214 208 208 202 203 203 198 198 199 163 164 128 128 93 93 57 63 63 33 33 39 39 45 44 44 49 49 48 84 83 119 118 154 154 190 184 )
fi
if [[ -z $_prompt_rainbow_index ]]; then
_prompt_rainbow_index=$(( RANDOM % (${#_prompt_rainbow[@]}-1) ))
fi
function _prompt_rainbow_inc_index {
[[ -z $_prompt_rainbow_pause ]] && _prompt_rainbow_index=$((_prompt_rainbow_index + 1))
if [[ $_prompt_rainbow_index -gt $((${#_prompt_rainbow[@]}-1)) ]]; then
_prompt_rainbow_index=0
fi
[[ -n $1 ]] && eval "$1=${_prompt_rainbow[$_prompt_rainbow_index]}"
}
function _prompt_hostname_random_color {
_prompt_hostname_color="$(( ( RANDOM % 203 ) + 17 ))"
}
if [[ -z $_prompt_hostname_color ]]; then
_prompt_hostname_random_color
fi
# rxvt specific code to properly set the window title
if [[ $TERM =~ rxvt.* ]]; then
# shellcheck disable=SC2016
_prompt_rxvt_trap_cmd=' _prompt_rxvt_set_title "$BASH_COMMAND"'
else
_prompt_rxvt_trap_cmd=''
fi
function _prompt_seg_command_state {
local _last_status=$2
local _res=""
if [[ $_previous_command != "_prompt_command" ]]; then
case $_last_status in
0 )
_res='\[\e[38;5;34m\]'" ✔ "
;;
* )
_res='\[\e[38;5;160m\]'" ✘ "
;;
esac
else
_res=" "
fi
eval "$1='$_res'"
}
function _prompt_seg_dir {
eval "$1=' \W '"
}
function _prompt_seg_git {
# shellcheck disable=SC2155
local _git_prompt=$(__git_ps1)
local _res=""
if [[ -n "$_git_prompt" ]]; then
# Strip leading space and parenthesis
_git_prompt="${_git_prompt:2:$((${#_git_prompt} - 3))}"
# Strip potential single quotes
_git_prompt="${_git_prompt//\'/}"
_res="  $_git_prompt "
fi
eval "$1='$_res'"
}
function _prompt_seg_hostname {
local _res=""
if [[ -n $SSH_CLIENT ]]; then
_res=" $_prompt_hostname "
fi
eval "$1='$_res'"
}
function _prompt_seg_virtualenv {
# Get Virtual Env
local _res=""
if [[ $VIRTUAL_ENV != "" ]]
then
# Strip out the path and just leave the env name
_res=" ${VIRTUAL_ENV##*/}"
else
# Not activated
_res=''
fi
eval "$1='$_res'"
}
_previous_command=""
_cur_command=""
function _prompt_command {
# Stash the status before we clobber it
local _last_status=$?
_prompt_set_arrow_char
local __arrow_char=$__prompt_arrow_char
local _rc
_prompt_rainbow_inc_index _rc
PS1='\[\e[38;5;'"$_rc"'m\]'
local seg
local _seg
local _seg_text=""
for i in "${!_prompt_config[@]}"; do
seg="${_prompt_config[$i]}"
_seg=( $seg )
"${_seg[0]}" _seg_text $_last_status
if [[ -n $_seg_text ]]; then
PS1+='\[\e[48;5;'"${_seg[1]}"'m\]'"$__arrow_char"
PS1+='\[\e[38;5;'"${_seg[2]}"'m\]'"$_seg_text"
PS1+='\[\e[38;5;'"${_seg[1]}"'m\]'
fi
_prompt_config[$i]="$seg"
_seg_text=""
done
PS1+='\[\e[49m\]'"$__arrow_char"'\[\e[0m\] '
# Reset status
(exit $_last_status)
}
function _prompt_rxvt_set_title {
if [[ $1 == "_prompt_command" ]]; then
printf '\e]0;%s\007' "urxvt - $(basename "$(pwd)")"
else
printf '\e]0;%s\007' "$1"
fi
}
# Trap commands to display status and title
# Only do this for login shells on the local machine
if [[ -z $SSH_CLIENT ]] && shopt -q login_shell; then
trap '_previous_command=$_cur_command; _cur_command=$BASH_COMMAND;'"$_prompt_rxvt_trap_cmd" DEBUG
else
trap '_previous_command=$_cur_command; _cur_command=$BASH_COMMAND;' DEBUG
fi
# Set a default config
# shellcheck disable=SC2128
if [[ -z $_prompt_config ]]; then
_prompt_config=(
"_prompt_seg_command_state 8 0"
"_prompt_seg_hostname $_prompt_hostname_color 15"
"_prompt_seg_dir 12 8"
"_prompt_seg_virtualenv 99 7"
"_prompt_seg_git 5 7"
)
fi
PROMPT_COMMAND="_prompt_command"
@nabrahamson
Copy link
Author

Now with python Virtualenv support

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