diff options
| -rw-r--r-- | .bash_prompt | 142 |
1 files changed, 63 insertions, 79 deletions
diff --git a/.bash_prompt b/.bash_prompt index e3c9a87..b00fb8f 100644 --- a/.bash_prompt +++ b/.bash_prompt @@ -12,7 +12,7 @@ __show-hostname () { case ${PS1_SHOWHOSTNAME} in (''|auto) - [ "${SSH_CONNECTION}" ];; + test "${SSH_CONNECTION}";; (yes) true;; (*) @@ -22,16 +22,13 @@ __show-hostname () __have-gitprompt () { - [ -f /usr/lib/git-core/git-sh-prompt ] + test -f /usr/lib/git-core/git-sh-prompt } __set-title () { local title=${USER} - if __show-hostname - then - title+="@${HOSTNAME}" - fi + __show-hostname && title+=@${HOSTNAME} title+=: title+=${PWD/~/\~} @@ -41,30 +38,26 @@ __set-title () # # ST is a "string terminator", either "ESC \" or "BEL". - echo -ne "\E]2;${title}\a" + printf $'\E]2;%s\a' "${title}" } -# In order to know how much space a prompt takes, Bash needs us to -# delimit non-printing characters with \[ and \]. +# Bash relies on \[ \] to distinguish non-printing characters in prompts. __start-nonprinting () { - if [ ${BUILDING_PS} ] - then - echo -en '\[' - fi + test ${BUILDING_PS} && printf '\[' } __end-nonprinting () { - if [ ${BUILDING_PS} ] - then - echo -en '\]' - fi + test ${BUILDING_PS} && printf '\]' } __fontify () { - local -A codes=( + local -r text=$1 + shift + + local -Ar codes=( [bold]=1 [dim]=2 [reverse]=7 @@ -73,91 +66,88 @@ __fontify () [blue]=34 ) - local text=$1 - shift - - __start-nonprinting - - echo -en '\E[' - - local i - for ((i=1; i<=$#; i++)) + local -a params=() + local c + for c do - echo -en ${codes[${!i}]} - - if ((i<$#)) - then - echo -en ';' - else - echo -en 'm' - fi + params+=(${codes[${c}]}) done + local params_seq + IFS=';' eval 'params_seq="${params[*]}"' + + __start-nonprinting + printf $'\E[%sm' "${params_seq}" __end-nonprinting - echo -en "${text}" + printf %s "${text}" __start-nonprinting - echo -en '\E[0m' + printf $'\E[0m' __end-nonprinting } __current-column () { - # Cf. console_codes(4) § ECMA-48 Status Report Commands + # Cf. console_codes(4) § ECMA-48 Status Report Commands. local position read -sdR -p$'\E[6n' position - local pattern='\[[0-9]+;([0-9]+)' + local -r pattern='\[[0-9]+;([0-9]+)' - if [[ ${position} =~ ${pattern} ]] - then - echo ${BASH_REMATCH[1]} - else + [[ ${position} =~ ${pattern} ]] || { echo 0 - fi + return + } + echo ${BASH_REMATCH[1]} } __signal-no-newline () { - echo $(__fontify ∅ bold red) + __fontify ∅ bold red + echo } __draw-rule () { - local i line - - for ((i=$(__current-column); i<COLUMNS; i++)) - do - line+=─ - done - - # If we do not add a newline, whatever comes after will be shoved - # offscreen when autowrap is off. - line+='\n' - - __fontify ${line} $@ + local -ir pos=$(__current-column) + local -ir rule_len=$((COLUMNS-pos)) + + local rule + # Hey Future Me 👋 Breaking this down: + # -v rule "put this in LINE, do not write to stdout" + # "%…s" "pad string…" + # - " … with spaces…" + # * " … with length given by next argument" + # ${rule_len} (padding length) + # ∅ (psych! no arg for %s, default to null string) + printf -v rule '%-*s' ${rule_len} + rule=${rule// /─} + + # Flush line to avoid future text being shoved offscreen when autowrap + # is off. + rule+=$'\n' + + __fontify "${rule}" "$@" } __write-context () { __fontify '\u' green - if __show-hostname - then + __show-hostname && { __fontify @ dim __fontify '\H' bold green - fi + } printf ' ' __fontify '\w' bold blue - if [ ${PS1_SHOWGITSTATUS} ] - then + test "${PS1_SHOWGITSTATUS}" && { printf ' ' __fontify "$(__git_ps1 '(%s)')" red - fi + } } __smart-term/set-ps1 () @@ -171,18 +161,16 @@ __smart-term/set-ps1 () __smart-term/refresh () { - local last_status=$? + local -ir rc=$? __set-title - if [ $(__current-column) -ne 1 ] - then - __signal-no-newline - fi + local -ir pos=$(__current-column) + ((pos != 1)) && __signal-no-newline - if [ ${last_status} -ne 0 ] + if ((rc)) then - __fontify "${last_status} " bold red + __fontify "${rc} " bold red __draw-rule dim red else __draw-rule dim @@ -193,16 +181,15 @@ __smart-term/refresh () __smart-term/init () { - ### Prompts. + # Prompts. - if __have-gitprompt - then + __have-gitprompt && { . /usr/lib/git-core/git-sh-prompt GIT_PS1_SHOWDIRTYSTATE=t GIT_PS1_SHOWUPSTREAM=auto PS1_SHOWGITSTATUS=t - fi + } PROMPT_COMMAND=__smart-term/refresh @@ -211,15 +198,12 @@ __smart-term/init () __fontify '… ' dim ) - ### Bindings. + # Bindings. bind -f ~/.bash_inputrc # Unset the TTY's "stop" char, so that readline receives C-s. - if tty -s - then - stty stop '' - fi + tty -s && stty stop '' } __dumb-term/set-ps1 () |
