#!/bin/bash -- # _ _ _ # | |__ __ _ ___| |__ _ __ _ __ ___ _ __ ___ _ __ | |_ # | '_ \ / _` / __| '_ \ | '_ \| '__/ _ \| '_ ` _ \| '_ \| __| # | |_) | (_| \__ \ | | | | |_) | | | (_) | | | | | | |_) | |_ # |_.__/ \__,_|___/_| |_| | .__/|_| \___/|_| |_| |_| .__/ \__| # |_| |_| term_red=$( tput setaf 1) \ term_green=$( tput setaf 2) \ term_yellow=$( tput setaf 3) \ term_blue=$( tput setaf 4) \ term_magenta=$(tput setaf 5) \ term_cyan=$( tput setaf 6) \ term_reset=$( tput sgr0 ) \ term_bold=$( tput bold ) \ term_reverse=$(tput rev ) \ prompt_time_color= prompt_time_text= \ prompt_path= \ || : # in case the last tput(1) command fails and errexit is on function updateprompt { local d MAPFILE old_rematch path_parts 'IFS=/' if [[ ${prompt_timer+is_set} ]]; then prompt_time_text=$(( (10#0${EPOCHREALTIME//[!0123456789]} - prompt_timer) / 1000 )) else prompt_time_text=0 fi if (( prompt_time_text <= 20 )); then prompt_time_color=$term_green elif (( prompt_time_text <= 100 )); then prompt_time_color=$term_yellow elif (( prompt_time_text <= 250 )); then prompt_time_color=$term_cyan elif (( prompt_time_text <= 500 )); then prompt_time_color=$term_blue elif (( prompt_time_text <= 999 )); then prompt_time_color=$term_magenta else prompt_time_color=$term_red \ prompt_time_text=$(( (prompt_time_text / 1000) % 1000 )) fi printf -v prompt_time_text %03d "$prompt_time_text" # using \w@P to make the prompt respect PROMPT_DIRTRIM prompt_path='\w' prompt_path=${prompt_path@P} case $prompt_path in \~) ;; /) prompt_path=/ ;; *) mapfile -td/ <<< "$prompt_path" MAPFILE[-1]=${MAPFILE[-1]%$'\n'} \ path_parts=() \ old_rematch=${BASH_REMATCH[*]@A} if [[ $old_rematch ]]; then if [[ ${BASH_REMATCH@a} ]] then old_rematch=${old_rematch/-/-g} else old_rematch='declare -g '$old_rematch fi elif declare -p BASH_REMATCH > /dev/null 2>&1 then old_rematch='declare -g BASH_REMATCH' fi for d in "${MAPFILE[@]}"; do if [[ $d =~ [[:alnum:]] || $d =~ [[:print:]] || -z $d ]]; then path_parts+=( "${BASH_REMATCH[0]}" ) else d=${d:0:1} prompt_path+=( "${d@Q}" ) fi done unset -v BASH_REMATCH eval " $old_rematch" prompt_path=${path_parts[*]} esac } # using [^...] instead of [!...] because ! is expanded in POSIX mode. PS0='${PS0:prompt_timer = 10#0${EPOCHREALTIME//[^0123456789]}:0}' PROMPT_COMMAND+=( updateprompt 'unset -v prompt_timer' ) PS1=\ '\[$prompt_time_color\]$prompt_time_text\[$term_reset\] '\ '($BASHPID) $prompt_path \[$term_red\]\$\[$term_reset\] '