From 700ac112a3dd2041de5fc2a6abd3781103c704a8 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 17 Dec 2016 17:46:15 +1300 Subject: Rename all pdksh stuff to ksh As part of a foray into more active use of ksh and derivatives. --- ksh/kshrc.d/prompt.ksh | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 ksh/kshrc.d/prompt.ksh (limited to 'ksh/kshrc.d/prompt.ksh') diff --git a/ksh/kshrc.d/prompt.ksh b/ksh/kshrc.d/prompt.ksh new file mode 100644 index 00000000..90e813f0 --- /dev/null +++ b/ksh/kshrc.d/prompt.ksh @@ -0,0 +1,201 @@ +# All of this is only known to work on OpenBSD's fork of pdksh +case $KSH_VERSION in + *'PD KSH'*) + case $(uname -s) in + OpenBSD) ;; + *) return ;; + esac + ;; + *) return ;; +esac + +# 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) + # Basic prompt shape depends on whether we're in SSH or not + PS1= + if [[ -n $SSH_CLIENT ]] || [[ -n $SSH_CONNECTION ]] ; then + PS1=$PS1'\u@\h:' + fi + PS1=$PS1'\w' + + # Add sub-commands; VCS, job, and return status checks + PS1=$PS1'$(prompt vcs)$(prompt job)$(prompt ret "$?")' + + # Add prefix and suffix + PS1='${PROMPT_PREFIX}'$PS1'${PROMPT_SUFFIX}' + + # Add terminating "$" or "#" sign + PS1=$PS1'\$' + + # Declare variables to contain terminal control strings + typeset format reset + + # Disregard output and error from these tput(1) calls + { + # Count available colors + typeset -i colors + colors=$(tput colors || tput Co) + + # Prepare reset code + reset=$(tput sgr0 || tput me) + + # Check if we have non-bold bright yellow available + if ((colors >= 16)) ; then + format=$( + : "${PROMPT_COLOR:=11}" + tput setaf "$PROMPT_COLOR" || + tput setaf "$PROMPT_COLOR" 0 0 || + tput AF "$PROMPT_COLOR" || + tput AF "$PROMPT_COLOR" 0 0 + ) + + # If we have only eight colors, use bold yellow + elif ((colors >= 8)) ; then + format=$( + : "${PROMPT_COLOR:=3}" + tput setaf "$PROMPT_COLOR" || + tput AF "$PROMPT_COLOR" + tput bold || tput md + ) + + # Otherwise, we just try bold + else + format=$(tput bold || tput md) + fi + + } >/dev/null 2>&1 + + # String it all together + PS1='\['"$format"'\]'"$PS1"'\['"$reset"'\] ' + PS2='> ' + PS3='? ' + PS4='+<$?> $LINENO:' + ;; + + # Git prompt function + git) + + # Wrap as compound command; we don't want to see output from any of + # these git(1) calls + { + # Bail if we're not in a work tree--or, implicitly, if we don't + # have git(1). + [[ -n $(git rev-parse --is-inside-work-tree) ]] || + return + + # Refresh index so e.g. git-diff-files(1) is accurate + git update-index --refresh + + # Find a local branch, remote branch, or tag (annotated or + # not), or failing all of that just show the short commit ID, + # in that order of preference; if none of that works, bail out + typeset name + name=$( + git symbolic-ref --quiet HEAD || + git describe --tags --exact-match HEAD || + git rev-parse --short HEAD + ) || return + name=${name##*/} + [[ -n $name ]] || return + + # Check various files in .git to flag processes + typeset proc + [[ -d .git/rebase-merge || -d .git/rebase-apply ]] && + proc=${proc:+"$proc",}'REBASE' + [[ -f .git/MERGE_HEAD ]] && + proc=${proc:+"$proc",}'MERGE' + [[ -f .git/CHERRY_PICK_HEAD ]] && + proc=${proc:+"$proc",}'PICK' + [[ -f .git/REVERT_HEAD ]] && + proc=${proc:+"$proc",}'REVERT' + [[ -f .git/BISECT_LOG ]] && + proc=${proc:+"$proc",}'BISECT' + + # Collect symbols representing repository state + typeset state + + # Upstream HEAD has commits after local HEAD; we're "behind" + (($(git rev-list --count 'HEAD..@{u}'))) && + state=${state}'<' + + # Local HEAD has commits after upstream HEAD; we're "ahead" + (($(git rev-list --count '@{u}..HEAD'))) && + state=${state}'>' + + # Tracked files are modified + git diff-files --no-ext-diff --quiet || + state=${state}'!!' + + # Changes are staged + git diff-index --cached --no-ext-diff --quiet HEAD || + state=${state}'+' + + # There are some untracked and unignored files + git ls-files --directory --error-unmatch --exclude-standard \ + --no-empty-directory --others -- ':/*' && + state=${state}'?' + + # There are stashed changes + git rev-parse --quiet --verify refs/stash && + state=${state}'^' + + } >/dev/null 2>&1 + + # 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%s)' \ + "${PROMPT_VCS:+git:}" "$name" "${proc:+:"$proc"}" "$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 + prompt "$vcs" && return + done + ;; + + # Show return status of previous command in angle brackets, if not zero + ret) + local ret=$2 + ((ret)) && printf '<%u>' "$ret" + ;; + + # Show the count of background jobs in curly brackets, if not zero + job) + typeset -i jobc + jobc=$(jobs -p | sed -n '$=') + ((jobc)) && printf '{%u}' "$jobc" + ;; + + # Print error + *) + printf 'prompt: Unknown command %s\n' "$1" >&2 + return 2 + ;; + + esac +} + +# Start with full-fledged prompt +prompt on -- cgit v1.2.3