# _ _ _ # _ __ ___ | |_ _ __ _| | ___ | |_ # | '_ \ / _ \| | | | |/ _` | |/ _ \| __| # | |_) | (_) | | |_| | (_| | | (_) | |_ # | .__/ \___/|_|\__, |\__, |_|\___/ \__| # |_| |___/ |___/ # # Polyglot Prompt # # A dynamic color Git prompt for zsh, bash, ksh93, mksh, pdksh, oksh, dash, # yash,busybox ash, and osh # # # Source this file from a relevant dotfile (e.g. .zshrc, .bashrc, .shrc, .kshrc, # .mkshrc, .yashrc, or ~/.config/oil/oshrc) thus: # # . /path/to/polyglot.sh # # Set $POLYGLOT_PROMPT_DIRTRIM to the number of directory elements you would # like to have displayed in your prompt (the default is 2). For example, # # POLYGLOT_PROMPT_DIRTRIM=3 # # results in # # ~/foo/bar/bat/quux # # displaying as # # ~/.../bar/bat/quux # # # Copyright 2017-2024 Alexandros Kozak # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # # # https://github.com/agkozak/polyglot # # shellcheck shell=ksh # shellcheck disable=SC2016,SC2034,SC2088,SC3024 # Only run in interactive shells case $- in *i*) ;; *) return ;; esac # Bail if the shell doesn't have command if ! type command > /dev/null 2>&1; then printf '%s\n' 'Polyglot Prompt does not support your shell.' >&2 return 1 fi # Don't let virtual env active scripts alter prompt VIRTUAL_ENV_DISABLE_PROMPT=1 ############################################################ # Display non-zero exit status # # Arguments: # $1 exit status of last command (always $?) ############################################################ _polyglot_exit_status() { case $1 in 0) return ;; *) printf '(%d) ' "$1" ;; esac } ########################################################### # Is the user connected via SSH? ########################################################### _polyglot_is_ssh() { [ -n "${SSH_CONNECTION-}${SSH_CLIENT-}${SSH_TTY-}" ] } ########################################################### # Provide the effective user ID ########################################################### _polyglot_euid() { case ${POLYGLOT_UNAME:=$(uname -s)} in SunOS) /usr/xpg4/bin/id -u ;; *) id -u ;; esac } ########################################################### # Is the user a superuser? ########################################################### _polyglot_is_superuser() { # shellcheck disable=SC3028 [ ${EUID:-$(_polyglot_euid)} -eq 0 ] } ########################################################### # Does the terminal support enough colors? ########################################################### _polyglot_has_colors() { [ -n "$ZSH_VERSION" ] && setopt LOCAL_OPTIONS NO_WARN_CREATE_GLOBAL # The DragonFly BSD system console has trouble displaying colors in pdksh case ${POLYGLOT_UNAME:=$(uname -s)} in DragonFly) case $(who am i) in *ttyv*) return 1 ;; esac ;; esac case $TERM in *-256color) POLYGLOT_TERM_COLORS=256 ;; vt100|dumb) POLYGLOT_TERM_COLORS=-1 ;; *) if command -v tput > /dev/null 2>&1; then case ${POLYGLOT_UNAME:=$(uname -s)} in FreeBSD|DragonFly) POLYGLOT_TERM_COLORS=$(tput Co) ;; UWIN*) POLYGLOT_TERM_COLORS=$(tput cols) ;; *) POLYGLOT_TERM_COLORS=$(tput colors) ;; esac else POLYGLOT_TERM_COLORS=-1 fi ;; esac if [ "${POLYGLOT_TERM_COLORS:-0}" -ge 8 ]; then unset POLYGLOT_TERM_COLORS return 0 else unset POLYGLOT_TERM_COLORS return 1 fi } ############################################################ # Emulation of bash's PROMPT_DIRTRIM for all other shells # and for bash before v4.0 # # In $PWD, substitute $HOME with ~; if the remainder of the # $PWD has more than a certain number of directory elements # to display (default: 2), abbreviate it with '...', e.g. # # $HOME/dotfiles/polyglot/img # # will be displayed as # # ~/.../polyglot/img # # If $1 is 0, no abbreviation will occur other than that # $HOME will be displayed as ~. # # Arguments: # $1 Number of directory elements to display ############################################################ _polyglot_prompt_dirtrim() { # Necessary for set -- $1 to undergo field separation in zsh [ -n "$ZSH_VERSION" ] && setopt LOCAL_OPTIONS SH_WORD_SPLIT \ NO_WARN_CREATE_GLOBAL NO_WARN_NESTED_VAR 2> /dev/null POLYGLOT_DIRTRIM_ELEMENTS="${1:-2}" # If root has / as $HOME, print /, not ~ [ "$PWD" = '/' ] && printf '%s' '/' && return [ "$PWD" = "$HOME" ] && printf '%s' '~' && return case $HOME in /) POLYGLOT_PWD_MINUS_HOME="$PWD" ;; # In case root's $HOME is / *) POLYGLOT_PWD_MINUS_HOME="${PWD#"$HOME"}" ;; esac if [ "$POLYGLOT_DIRTRIM_ELEMENTS" -eq 0 ]; then [ "$HOME" = '/' ] && printf '%s' "$PWD" && return case $PWD in ${HOME}*) printf '~%s' "$POLYGLOT_PWD_MINUS_HOME" ;; *) printf '%s' "$PWD" ;; esac else # Calculate the part of $PWD that will be displayed in the prompt POLYGLOT_OLD_IFS="$IFS" IFS='/' # shellcheck disable=SC2086 set -- $POLYGLOT_PWD_MINUS_HOME shift # Discard empty first field preceding / # Discard path elements > $POLYGLOT_PROMPT_DIRTRIM while [ $# -gt "$POLYGLOT_DIRTRIM_ELEMENTS" ]; do shift done # Reassemble the remaining path elements with slashes while [ $# -ne 0 ]; do POLYGLOT_ABBREVIATED_PATH="${POLYGLOT_ABBREVIATED_PATH}/$1" shift done IFS="$POLYGLOT_OLD_IFS" # If the working directory has not been abbreviated, display it thus if [ "$POLYGLOT_ABBREVIATED_PATH" = "${POLYGLOT_PWD_MINUS_HOME}" ]; then if [ "$HOME" = '/' ]; then printf '%s' "$PWD" else case $PWD in ${HOME}*) printf '~%s' "${POLYGLOT_PWD_MINUS_HOME}" ;; *) printf '%s' "$PWD" ;; esac fi # Otherwise include an ellipsis to show that abbreviation has taken place else if [ "$HOME" = '/' ]; then printf '...%s' "$POLYGLOT_ABBREVIATED_PATH" else case $PWD in ${HOME}*) printf '~/...%s' "$POLYGLOT_ABBREVIATED_PATH" ;; *) printf '...%s' "$POLYGLOT_ABBREVIATED_PATH" ;; esac fi fi fi unset POLYGLOT_DIRTRIM_ELEMENTS POLYGLOT_PWD_MINUS_HOME POLYGLOT_OLD_IFS \ POLYGLOT_ABBREVIATED_PATH } ########################################################### # Display current branch name, followed by symbols # representing changes to the working copy # # Arguments: # $1 If ksh, escape ! as !! # # shellcheck disable=SC2120 ########################################################### _polyglot_branch_status() { [ -n "$ZSH_VERSION" ] && setopt LOCAL_OPTIONS NO_WARN_CREATE_GLOBAL \ NO_WARN_NESTED_VAR > /dev/null 2>&1 POLYGLOT_REF="$(env git symbolic-ref --quiet HEAD 2> /dev/null)" case $? in # See what the exit code is. 0) ;; # $POLYGLOT_REF contains the name of a checked-out branch. 128) return ;; # No Git repository here. # Otherwise, see if HEAD is in a detached state. *) POLYGLOT_REF="$(env git rev-parse --short HEAD 2> /dev/null)" || return ;; esac if [ -n "$POLYGLOT_REF" ]; then if [ "${POLYGLOT_SHOW_UNTRACKED:-1}" -eq 0 ]; then POLYGLOT_GIT_STATUS=$(LC_ALL=C GIT_OPTIONAL_LOCKS=0 env git status -uno 2>&1) else POLYGLOT_GIT_STATUS=$(LC_ALL=C GIT_OPTIONAL_LOCKS=0 env git status 2>&1) fi POLYGLOT_SYMBOLS='' case $POLYGLOT_GIT_STATUS in *' have diverged,'*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}&*" ;; esac case $POLYGLOT_GIT_STATUS in *'Your branch is behind '*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}&" ;; esac case $POLYGLOT_GIT_STATUS in *'Your branch is ahead of '*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}*" ;; esac case $POLYGLOT_GIT_STATUS in *'new file: '*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}+" ;; esac case $POLYGLOT_GIT_STATUS in *'deleted: '*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}x" ;; esac case $POLYGLOT_GIT_STATUS in *'modified: '*) if [ "$1" = 'ksh' ]; then POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}!!" else POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}!" fi ;; esac case $POLYGLOT_GIT_STATUS in *'renamed: '*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}>" ;; esac case $POLYGLOT_GIT_STATUS in *'Untracked files:'*) POLYGLOT_SYMBOLS="${POLYGLOT_SYMBOLS}?" ;; esac [ -n "$POLYGLOT_SYMBOLS" ] && POLYGLOT_SYMBOLS=" $POLYGLOT_SYMBOLS" printf ' (%s%s)' "${POLYGLOT_REF#refs/heads/}" "$POLYGLOT_SYMBOLS" fi unset POLYGLOT_REF POLYGLOT_GIT_STATUS POLYGLOT_SYMBOLS } ########################################################### # Native sh alternative to basename. See # https://github.com/dylanaraps/pure-sh-bible # # Arguments: # $1 Filename # $2 Suffix ########################################################### _polyglot_basename() { POLYGLOT_BASENAME_DIR=${1%"${1##*[!/]}"} POLYGLOT_BASENAME_DIR=${POLYGLOT_BASENAME_DIR##*/} POLYGLOT_BASENAME_DIR=${POLYGLOT_BASENAME_DIR%"$2"} printf '%s\n' "${POLYGLOT_BASENAME_DIR:-/}" unset POLYGLOT_BASENAME_DIR } ########################################################### # Tests to see if the current shell is busybox ash ########################################################### _polyglot_is_busybox() { case $(help 2> /dev/null) in 'Built-in commands:'*) return 0 ;; *) return 1 ;; esac } ########################################################### # Test to see if the current shell is pdksh or oksh ########################################################### _polyglot_is_pdksh() { case $KSH_VERSION in *'PD KSH'*) if [ "${POLYGLOT_UNAME:=$(uname -s)}" = 'OpenBSD' ] || [ "${0#-}" = 'oksh' ]; then POLYGLOT_KSH_BANG='ksh' fi return 0 ;; *) return 1 ;; esac } ########################################################### # Test to see if the current shell is dtksh (Desktop Korn # Shell). ########################################################### _polyglot_is_dtksh() { case ${0#-} in *dtksh) return 0 ;; *) return 1 ;; esac } ########################################################### # Test to see if sh is really dash ########################################################### _polyglot_sh_is_dash() { case $(ls -l "$(command -v "${0#-}")") in *dash*) return 0 ;; *) return 1 ;; esac } _polyglot_is_yash() { case "${0#-}" in *yash) return 0 ;; *) return 1 ;; esac } ########################################################### # Output virtual environment name ########################################################### _polyglot_venv() { # pipenv/poetry: when the virtualenv is in the project directory if [ "${VIRTUAL_ENV##*/}" = '.venv' ]; then POLYGLOT_VENV=${VIRTUAL_ENV%/.venv} POLYGLOT_VENV=${POLYGLOT_VENV##*/} # pipenv elif [ -n "$PIPENV_ACTIVE" ]; then POLYGLOT_VENV=${VIRTUAL_ENV%-*} POLYGLOT_VENV=${POLYGLOT_VENV##*/} # virtualenv/venv elif [ -n "$VIRTUAL_ENV" ]; then POLYGLOT_VENV=${VIRTUAL_ENV##*/} # conda elif [ -n "$CONDA_DEFAULT_ENV" ]; then POLYGLOT_VENV=$CONDA_DEFAULT_ENV fi [ -n "$POLYGLOT_VENV" ] && printf '(%s) ' "$POLYGLOT_VENV" unset POLYGLOT_VENV } ##################################################################### # zsh ##################################################################### # Make sure that ZSH is not emulating ksh or bash if [ -n "$ZSH_VERSION" ] && [ "${0#-}" != 'ksh' ] && [ "${0#-}" != 'bash' ] && [ "${0#-}" != 'sh' ]; then setopt PROMPT_SUBST ########################################################### # Runs right before the prompt is displayed # Imitates bash's PROMPT_DIRTRIM behavior and calculates # working branch and working copy status ########################################################### _polyglot_precmd() { psvar[2]=$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM") psvar[3]=$(_polyglot_branch_status) psvar[5]=$(_polyglot_venv) PS1='' # The ZSH vi mode indicator won't work in Emacs shell (but it does in term # and ansi-term) if [ "$TERM" != 'dumb' ]; then PS1+='%(4V.:.+)' fi if _polyglot_has_colors; then PS1+='%(?..%B%F{red}(%?%)%b%f )' PS1+='%5v' PS1+='%(!.%S.%B%F{green})%n%1v%(!.%s.%f%b) ' PS1+='%B%F{blue}%2v%f%b' PS1+='%F{yellow}%3v%f %# ' else PS1+='%(?..(%?%) )' PS1+='%5v' PS1+='%(!.%S.)%n%1v%(!.%s.) ' PS1+='%2v' PS1+='%3v %# ' fi } ########################################################### # Redraw the prompt when the vi mode changes # # Whn in vi mode, the prompt will use a bash 4.3-style # mode indicator at the beginniing of the line: '+' for # insert mode; ':' for command mode # # Underscores are used in this function's name to keep # dash from choking on hyphens ########################################################### _polyglot_zle_keymap_select() { [ "$KEYMAP" = 'vicmd' ] && psvar[4]='vicmd' || psvar[4]='' zle reset-prompt zle -R } zle -N _polyglot_zle_keymap_select zle -A _polyglot_zle_keymap_select zle-keymap-select zle -A _polyglot_zle_keymap_select zle-line-init ########################################################### # Redraw prompt when terminal size changes ########################################################### TRAPWINCH() { zle && zle -R } # TODO: add-zsh-hook was added in ZSH v4.3.4. It would be nice to be # compatible with even earlier versions of ZSH, but that seems to require # use of array syntax that is incompatible with ash. autoload add-zsh-hook add-zsh-hook precmd _polyglot_precmd # Only display the $HOSTNAME for an ssh connection, except for a superuser if _polyglot_is_ssh || _polyglot_is_superuser; then psvar[1]="@${HOST%%\.*}" else psvar[1]='' fi unset RPROMPT # Clean up detritus from previously loaded prompts ##################################################################### # bash ##################################################################### elif [ -n "$BASH_VERSION" ]; then ########################################################### # Create the bash $PROMPT_COMMAND # # If $1 is 0, bash's PROMPT_DIRTRIM abbreviations will be # disabled; the only abbreviation that will occur is that # $HOME will be displayed as ~. # # Arguments: # $1 Number of directory elements to display ########################################################### _polyglot_prompt_command() { # $POLYGLOT_PROMPT_DIRTRIM must be greater than 0 and defaults to 2 [ "$1" ] && PROMPT_DIRTRIM=$1 || PROMPT_DIRTRIM=2 if ! _polyglot_is_superuser; then if _polyglot_has_colors; then PS1="\[\e[01;31m\]\$(_polyglot_exit_status \$?)\[\e[0m\]" PS1+="\$(_polyglot_venv)" PS1+="\[\e[01;32m\]\u$(printf '%s' "$POLYGLOT_HOSTNAME_STRING")\[\e[0m\] " case $BASH_VERSION in # bash, before v4.0, did not have $PROMPT_DIRTRIM 1.*|2.*|3.*) PS1+="\[\e[01;34m\]\$(_polyglot_prompt_dirtrim \$POLYGLOT_PROMPT_DIRTRIM)\[\e[0m\]" ;; *) PS1+="\[\e[01;34m\]\w\[\e[0m\]" ;; esac PS1+="\[\e[33m\]\$(_polyglot_branch_status)\[\e[0m\] \$ " else PS1="\$(_polyglot_exit_status \$?)" PS1+="\$(_polyglot_venv)" PS1+="\u$(printf '%s' "$POLYGLOT_HOSTNAME_STRING") " case $BASH_VERSION in 1.*|2.*|3.*) PS1="\$(_polyglot_prompt_dirtrim \$POLYGLOT_PROMPT_DIRTRIM)" ;; *) PS1+="\w" ;; esac PS1+="\$(_polyglot_branch_status) \$ " fi else # Superuser if _polyglot_has_colors; then PS1="\[\e[01;31m\]\$(_polyglot_exit_status \$?)\[\e[0m\]" PS1+="\$(_polyglot_venv)" PS1+="\[\e[7m\]\u@\h\[\e[0m\] " case $BASH_VERSION in 1.*|2.*|3.*) PS1+="\[\e[01;34m\]\$(_polyglot_prompt_dirtrim \$POLYGLOT_PROMPT_DIRTRIM)\[\e[0m\]" ;; *) PS1+="\[\e[01;34m\]\w\[\e[0m\]" ;; esac PS1+="\[\e[33m\]\$(_polyglot_branch_status)\[\e[0m\] # " else PS1="\$(_polyglot_exit_status \$?)" PS1+="\$(_polyglot_venv)" PS1+="\[\e[7m\]\u@\h\[\e[0m\] " case $BASH_VERSION in 1.*|2.*|3.*) PS1+="\$(_polyglot_prompt_dirtrim \$POLYGLOT_PROMPT_DIRTRIM)" ;; *) PS1+="\w" ;; esac PS1+="\$(_polyglot_branch_status) # " fi fi } # Only display the $HOSTNAME for an ssh connection if _polyglot_is_ssh; then POLYGLOT_HOSTNAME_STRING='@\h' else POLYGLOT_HOSTNAME_STRING='' fi PROMPT_COMMAND='_polyglot_prompt_command $POLYGLOT_PROMPT_DIRTRIM' # vi command mode if [ "$TERM" != 'dumb' ]; then # Line editing not enabled in Emacs shell bind 'set show-mode-in-prompt' # Since bash 4.3 bind 'set vi-ins-mode-string "+"' bind 'set vi-cmd-mode-string ":"' fi ##################################################################### # ksh93, mksh, and zsh in bash, ksh, and sh emulation mode ##################################################################### elif [ -n "$KSH_VERSION" ] || _polyglot_is_dtksh || [ -n "$ZSH_VERSION" ] && ! _polyglot_is_pdksh ; then # Only display the $HOSTNAME for an ssh connection if _polyglot_is_ssh || _polyglot_is_superuser; then POLYGLOT_HOSTNAME_STRING=$(hostname) POLYGLOT_HOSTNAME_STRING="@${POLYGLOT_HOSTNAME_STRING%%\.*}" else POLYGLOT_HOSTNAME_STRING='' fi if [ "${0#-}" = 'bash' ] || [ "${0#-}" = 'sh' ]; then POLYGLOT_KSH_BANG='' else case $KSH_VERSION in *MIRBSD*) POLYGLOT_KSH_BANG='' ;; *) POLYGLOT_KSH_BANG='ksh' ;; esac fi case $KSH_VERSION in *MIRBSD*) # To know how long the prompt is, and thus to know how far it is to the # edge of the screen, mksh requires an otherwise unused character (in this # case \001) followed by a carriage return at the beginning of the # prompt, which is then used to mark off escape sequences as zero-length. # See https://www.mirbsd.org/htman/i386/man1/mksh.htm if ! _polyglot_is_superuser; then if _polyglot_has_colors; then PS1=$(print "\001\r\001\E[31;1m\001") PS1+='$(_polyglot_exit_status $?)' PS1+=$(print "\001\E[0m") PS1+='$(_polyglot_venv)' PS1+=$(print "\E[32;1m\001") PS1+='${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING' PS1+=$(print "\001\E[0m\001") PS1+=' ' PS1+=$(print "\001\E[34;1m\001") PS1+='$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")' PS1+=$(print "\001\E[0m\E[33m\001") PS1+='$(_polyglot_branch_status $POLYGLOT_KSH_BANG)' PS1+=$(print "\001\E[0m\001") PS1+=' \$ ' else PS1='$(_polyglot_exit_status $?)' PS1+='$(_polyglot_venv)' PS1+='${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING ' PS1+='$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")' PS1+='$(_polyglot_branch_status $POLYGLOT_KSH_BANG)' PS1+=' \$ ' fi else # Superuser if _polyglot_has_colors; then PS1=$(print "\001\r\001\E[31;1m\001") PS1+='$(_polyglot_exit_status $?)' PS1+=$(print "\001\E[0m") PS1+='$(_polyglot_venv)' PS1+=$(print "\E[7m\001") PS1+='${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING' PS1+=$(print "\001\E[0m\001") PS1+=' ' PS1+=$(print "\001\E[34;1m\001") PS1+='$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")' PS1+=$(print "\001\E[0m\E[33m\001") PS1+='$(_polyglot_branch_status $POLYGLOT_KSH_BANG)' PS1+=$(print "\001\E[0m\001") PS1+=' # ' else PS1=$(print "\001\r") PS1+='$(_polyglot_exit_status $?)' PS1+='$(_polyglot_venv)' PS1+=$(print "\001\E[7m\001") PS1+='${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING' PS1+=$(print "\001\E[0m\001") PS1+=' ' PS1+='$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")' PS1+='$(_polyglot_branch_status $POLYGLOT_KSH_BANG)' PS1+=' # ' fi fi ;; *) if ! _polyglot_is_superuser; then # zsh emulating other shells doesn't handle colors well if _polyglot_has_colors && [ -z "$ZSH_VERSION" ]; then # FreeBSD sh chokes on ANSI C quoting, so I'll avoid it PS1="$(print '\E[31;1m$(_polyglot_exit_status $?)\E[0m$(_polyglot_venv)\E[32;1m${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING\E[0m \E[34;1m$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")\E[0m\E[33m$(_polyglot_branch_status $POLYGLOT_KSH_BANG)\E[0m \$ ')" else PS1='$(_polyglot_exit_status $?)$(_polyglot_venv)${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING $(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")$(_polyglot_branch_status $POLYGLOT_KSH_BANG) \$ ' fi else # Superuser if _polyglot_has_colors && [ -z "$ZSH_VERSION" ]; then PS1="$(print '\E[31;1m$(_polyglot_exit_status $?)\E[0m$(_polyglot_venv)\E[7m${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING\E[0m \E[34;1m$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")\E[0m\E[33m$(_polyglot_branch_status $POLYGLOT_KSH_BANG)\E[0m\E[0m # ')" else PS1="$(print '$(_polyglot_exit_status $?)$(_polyglot_venv)\E[7m${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING\E[0m $(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")$(_polyglot_branch_status $POLYGLOT_KSH_BANG) # ')" fi fi ;; esac #################################################################### # pdksh, oksh, dash, busybox ash, yash, osh, # and zsh in sh emulation mode #################################################################### elif _polyglot_is_pdksh || [ "${0#-}" = 'dash' ] || _polyglot_is_busybox || _polyglot_is_yash || _polyglot_sh_is_dash || [ "${0#-}" = 'osh' ]; then # Only display the $HOSTNAME for an ssh connection if _polyglot_is_ssh || _polyglot_is_superuser; then POLYGLOT_HOSTNAME_STRING=$(hostname) POLYGLOT_HOSTNAME_STRING="@${POLYGLOT_HOSTNAME_STRING%%\.*}" else POLYGLOT_HOSTNAME_STRING='' fi # pdksh uses an arbitrary non-printing character to delimit color escape # sequences in the prompt. In practice, however, it is impossible to find # one single non-printing character that will work with all operating systems # and terminals. The Polyglot Prompt defaults to \021 for OpenBSD/NetBSD # and \016 for everything else. If you want to specify your own non-printing # character, do so thus: # # POLYGLOT_NP="\016" # Set this variable to whatever value you like # # Or set POLYGLOT_PDKSH_COLORS=0 to disable color entirely in pdksh. case ${POLYGLOT_UNAME} in NetBSD*|OpenBSD*) POLYGLOT_NP=${POLYGLOT_NP:-"\021"} ;; *) POLYGLOT_NP=${POLYGLOT_NP:-"\016"} ;; esac if _polyglot_is_pdksh && _polyglot_has_colors && [ ${POLYGLOT_PDKSH_COLORS:-1} -ne 0 ]; then PS1=$(print "$POLYGLOT_NP\r") case $POLYGLOT_UNAME in NetBSD*|OpenBSD*) PS1=$PS1$(print "$POLYGLOT_NP") ;; esac PS1=$PS1$(print "\033[31;1m$POLYGLOT_NP") PS1=$PS1'$(_polyglot_exit_status $?)' PS1=$PS1$(print "$POLYGLOT_NP\033[0m$POLYGLOT_NP") PS1=$PS1'$(_polyglot_venv)' if ! _polyglot_is_superuser; then PS1=$PS1$(print "$POLYGLOT_NP\033[32;1m$POLYGLOT_NP") else PS1=$PS1$(print "$POLYGLOT_NP\033[7m$POLYGLOT_NP") fi PS1=$PS1'${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING' PS1=$PS1$(print "$POLYGLOT_NP\033[0m$POLYGLOT_NP") PS1=$PS1' ' PS1=$PS1$(print "$POLYGLOT_NP\033[34;1m$POLYGLOT_NP") PS1=$PS1'$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")' PS1=$PS1$(print "$POLYGLOT_NP\033[0m\033[33m$POLYGLOT_NP") PS1=$PS1'$(_polyglot_branch_status $POLYGLOT_KSH_BANG)' PS1=$PS1$(print "$POLYGLOT_NP\033[0m$POLYGLOT_NP") PS1=$PS1' \$ ' elif _polyglot_is_yash || [ "${0#-}" = 'osh' ] && _polyglot_has_colors; then PS1='\[\e[01;31m\]$(_polyglot_exit_status $?)\[\e[0m\]' PS1=$PS1'$(_polyglot_venv)' if ! _polyglot_is_superuser; then PS1=$PS1'\[\e[01;32m\]${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING\[\e[0m\] ' else PS1=$PS1'\[\e[7m\]${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING\[\e[0m\] ' fi PS1=$PS1'\[\e[01;34m\]$(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")\[\e[0m\]' PS1=$PS1'\[\e[33m\]$(_polyglot_branch_status $POLYGLOT_KSH_BANG)\[\e[0m\] \$ ' else PS1='$(_polyglot_exit_status $?)$(_polyglot_venv)${LOGNAME:-$(logname)}$POLYGLOT_HOSTNAME_STRING $(_polyglot_prompt_dirtrim "$POLYGLOT_PROMPT_DIRTRIM")$(_polyglot_branch_status $POLYGLOT_KSH_BANG) ' if ! _polyglot_is_superuser; then PS1=$PS1'$ ' else PS1=$PS1'# ' fi fi else printf '%s\n' 'Polyglot Prompt does not support your shell.' >&2 fi # Clean up environment unset -f _polyglot_is_ssh _polyglot_basename _polyglot_is_busybox \ _polyglot_is_dtksh _polyglot_is_pdksh _polyglot_sh_is_dash # vim: ts=2:et:sts=2:sw=2