blob: f9dfa584762d70067d6766d82ccb150d43dc4c92 (
plain) (
tree)
|
|
# All of this is only known to work on OpenBSD's fork of pdksh
[[ $(uname -s) == OpenBSD ]] || return
# Frontend to controlling prompt
prompt() {
# If no arguments, print the prompt strings as they are
if ! (($#)) ; then
printf '%s\n' PS1="$PS1" PS2="$PS2" PS3="$PS3" PS4="$PS4"
return
fi
# What's done next depends on the first argument to the function
case $1 in
# Turn complex, colored PS1 and debugging PS4 prompts on
on)
# Set up prompt, including optional PROMPT_PREFIX and PROMPT_SUFFIX
# variables
PS1='\u@\h:\w'
PS1=$PS1'$(prompt vcs)'
PS1=$PS1'$(prompt job)'
PS1='${PROMPT_PREFIX}'$PS1
PS1=$PS1'${PROMPT_SUFFIX}'
PS1=$PS1'\$'
# Count available colors
typeset -i colors
colors=$( {
tput Co || tput colors
} 2>/dev/null )
# Prepare reset code
typeset reset
reset=$( {
tput me || tput sgr0
} 2>/dev/null )
# Decide prompt color formatting based on color availability
typeset format
case $colors in
# Check if we have non-bold bright green available
256)
format=$( {
: "${PROMPT_COLOR:=12}"
tput AF "$PROMPT_COLOR" ||
tput setaf "$PROMPT_COLOR" ||
tput AF "$PROMPT_COLOR" 0 0 ||
tput setaf "$PROMPT_COLOR" 0 0
} 2>/dev/null )
;;
# If we have only eight colors, use bold green
8)
format=$( {
: "${PROMPT_COLOR:=4}"
tput AF "$PROMPT_COLOR" ||
tput setaf "$PROMPT_COLOR"
tput md || tput bold
} 2>/dev/null )
;;
# For all other terminals, we assume non-color (!), and we just
# use bold
*)
format=$( {
tput md || tput bold
} 2>/dev/null )
;;
esac
# String it all together
PS1='\['"$format"'\]'"$PS1"'\['"$reset"'\] '
PS2='> '
PS3='? '
PS4='+<$?> $LINENO:'
;;
# Git prompt function
git)
# Bail if we have no git(1)
if ! hash git 2>/dev/null ; then
return 1
fi
# Attempt to determine git branch, bail if we can't
typeset branch
branch=$( {
git symbolic-ref --quiet HEAD ||
git rev-parse --short HEAD
} 2>/dev/null )
if [[ ! -n $branch ]] ; then
return 1
fi
branch=${branch##*/}
# Refresh index so e.g. git-diff-files(1) is accurate
git update-index --refresh >/dev/null
# Collect symbols representing repository state
typeset state
# Upstream HEAD has commits after local HEAD; we're "behind"
(($(git rev-list --count 'HEAD..@{u}' 2>/dev/null) > 0)) &&
state=${state}\<
# Local HEAD has commits after upstream HEAD; we're "ahead"
(($(git rev-list --count '@{u}..HEAD' 2>/dev/null) > 0)) &&
state=${state}\>
# Tracked files are modified
git diff-files --quiet ||
state=${state}'!!'
# Changes are staged
git diff-index --cached --quiet HEAD ||
state=${state}\+
# There are some untracked and unignored files
[[ -n $(git ls-files --others --exclude-standard) ]] &&
state=${state}\?
# There are stashed changes
git rev-parse --quiet --verify refs/stash >/dev/null &&
state=${state}\^
# Print the status in brackets; add a git: prefix only if there
# might be another VCS prompt (because PROMPT_VCS is set)
printf '(%s%s%s)' "${PROMPT_VCS:+git:}" "${branch:-unknown}" "$state"
;;
# Revert to simple inexpensive prompts
off)
PS1='\$ '
PS2='> '
PS3='? '
PS4='+ '
;;
# VCS wrapper prompt function; print the first relevant prompt, if any
vcs)
typeset vcs
for vcs in "${PROMPT_VCS[@]:-git}" ; do
if prompt "$vcs" ; then
return
fi
done
;;
# Show the count of background jobs in curly brackets, if not zero
job)
typeset -i jobc
jobc=$(jobs -p | sed -n '$=')
if ((jobc > 0)) ; then
printf '{%u}' "$jobc"
fi
;;
# Print error
*)
printf 'prompt: Unknown command %s\n' "$1" >&2
return 2
;;
esac
}
# Start with full-fledged prompt
prompt on
|