218 lines
7.9 KiB
Bash
218 lines
7.9 KiB
Bash
#!/bin/bash
|
|
# shebang for syntax highlighting purposes
|
|
|
|
# Colors
|
|
_NON="\[\033[0m\]"
|
|
_BLD="\[\033[1m\]"
|
|
_BLK="\[\033[30m\]"
|
|
_RED="\[\033[31m\]"
|
|
_GRN="\[\033[32m\]"
|
|
_YLW="\[\033[33m\]"
|
|
_BLU="\[\033[34m\]"
|
|
_PRP="\[\033[35m\]"
|
|
_CYN="\[\033[36m\]"
|
|
_WHT="\[\033[37m\]"
|
|
|
|
# Number of guix packages to show before truncating in `guix shell`
|
|
_GUIX_MAXLIST=1
|
|
|
|
# Minimum microseconds to show a count
|
|
_MIN_US=0
|
|
|
|
__debug_trap() {
|
|
# Set necessary pre-command variables (PROMPT_COMMAND is a
|
|
# command so its excluded here)
|
|
if [[ "$BASH_COMMAND" != "$PROMPT_COMMAND"
|
|
&& "$LAST_BASH_COMMAND" == "$PROMPT_COMMAND" ]]; then
|
|
INC_TIME=1
|
|
LAST_RT="$EPOCHREALTIME" # This should be the last
|
|
# thing done in this function
|
|
fi
|
|
LAST_BASH_COMMAND="$BASH_COMMAND" # But this needs to be
|
|
}
|
|
|
|
trap '__debug_trap' DEBUG
|
|
|
|
__get_cmd_time() {
|
|
# Set hours minutes seconds and remove preceding zeros
|
|
local YEAR
|
|
local DAYS
|
|
local HOUR
|
|
local MINS
|
|
local SECS
|
|
((YEAR=10#$(($(TZ=UTC printf '%(%Y)T' "$CMD_TIME")))-1970))
|
|
((DAYS=10#$(TZ=UTC printf '%(%j)T' "$CMD_TIME")))
|
|
((HOUR=10#$(TZ=UTC printf '%(%H)T' "$CMD_TIME")))
|
|
((MINS=10#$(TZ=UTC printf '%(%M)T' "$CMD_TIME")))
|
|
((SECS=10#$(TZ=UTC printf '%(%S)T' "$CMD_TIME")))
|
|
|
|
# Choose whether or not to print hours minutes and seconds
|
|
[[ $CMD_TIME -ge 31536000 ]] && printf '%sy ' "${YEAR}"
|
|
[[ $CMD_TIME -ge 86400 ]] && printf '%sd ' "${DAYS}"
|
|
[[ $CMD_TIME -ge 3600 ]] && printf '%sh ' "${HOUR}"
|
|
[[ $CMD_TIME -ge 60 ]] && printf '%sm ' "${MINS}"
|
|
[[ $CMD_TIME -ge 1 ]] && printf '%ss ' "${SECS}"
|
|
[[ $CMD_US -ge $_MIN_US ]] && printf '%sμs' "${CMD_US:-0}"
|
|
}
|
|
|
|
__sig() {
|
|
# Giant switch case for getting the name of the signal (`kill -l`)
|
|
local ITR=0
|
|
local RET
|
|
for RET in "$@"; do
|
|
if [[ $ITR != 0 ]]; then
|
|
printf '%s|%s' "$_WHT" "$_RED"
|
|
fi
|
|
((ITR++))
|
|
case $RET in
|
|
126): "ACCES" ;;
|
|
127): "NOENT" ;;
|
|
129): "HUP" ;;
|
|
130): "INT" ;;
|
|
131): "QUIT" ;;
|
|
132): "ILL" ;;
|
|
133): "TRAP" ;;
|
|
134): "ABRT" ;;
|
|
135): "BUS" ;;
|
|
136): "FPE" ;;
|
|
137): "KILL" ;;
|
|
138): "USR"1 ;;
|
|
139): "SEGV" ;;
|
|
140): "USR"2 ;;
|
|
141): "PIPE" ;;
|
|
142): "ALRM" ;;
|
|
143): "TERM" ;;
|
|
144): "STKFLT" ;;
|
|
145): "CHLD" ;;
|
|
146): "CONT" ;;
|
|
147): "STOP" ;;
|
|
148): "TSTP" ;;
|
|
149): "TTIN" ;;
|
|
150): "TTOU" ;;
|
|
151): "URG" ;;
|
|
152): "XCPU" ;;
|
|
153): "XFSZ" ;;
|
|
154): "VTALRM" ;;
|
|
155): "PROF" ;;
|
|
156): "WINCH" ;;
|
|
157): "IO" ;;
|
|
158): "PWR" ;;
|
|
159): "SYS" ;;
|
|
16[3-9]|1[7-8][0-9]|19[0-2]): "RT$((RET-128))" ;; # Savagery
|
|
*): "$RET" ;; # Print exit code if not in list
|
|
esac
|
|
printf '%s' "$_"
|
|
done
|
|
}
|
|
|
|
__ssh() {
|
|
local CON=($SSH_CONNECTION)
|
|
local SRV_IP="${CON[2]}"
|
|
[[ -z "$SRV_IP" ]] && return
|
|
local SRV_PORT="${CON[3]}"
|
|
# 4 chars from startand 4 chars from end
|
|
local SRV_IP_CUT="${_CYN}${SRV_IP}"
|
|
[[ ${#SRV_IP} -gt 8 ]] && local SRV_IP_CUT="${_CYN}${SRV_IP:0:4}${_WHT}*${_CYN}${SRV_IP: -4}"
|
|
|
|
printf '%s' "${_GRN}${_BLU}[${SRV_IP_CUT}${_PRP}${_BLD}:${_NON}${_CYN}${SRV_PORT}${_BLU}]${_NON}"
|
|
}
|
|
|
|
__guix_env() {
|
|
local re='[\(]?\("([0-9a-z+_:-]*)"$'
|
|
local re1='"([a-z]*)"$'
|
|
if [[ "$GUIX_ENVIRONMENT" ]]; then
|
|
local line
|
|
local PACKAGES=($(while read -r line; do
|
|
[[ "$line" =~ $re ]] && printf '%s ' "${BASH_REMATCH[1]}"
|
|
done < $GUIX_ENVIRONMENT/manifest))
|
|
local OUTPUTS=($(while read -r line; do
|
|
if [[ "$line" =~ $re1 ]]; then
|
|
local match="${BASH_REMATCH[1]}"
|
|
[[ ! "${PACKAGES[*]}" =~ "$match" ]] && printf '%s ' "$match"
|
|
fi
|
|
done < $GUIX_ENVIRONMENT/manifest))
|
|
if [[ ${#PACKAGES[@]} -eq $((_GUIX_MAXLIST+1)) ]]; then
|
|
printf "${_BLD}${_BLU}[${_NON}${_YLW}Guix${_NON}: ${_WHT}%s ${_NON}+ ${_PRP}%d ${_NON}pkg${_BLD}${_BLU}] " "${PACKAGES[0]}$([[ ${OUTPUTS[0]} && ${OUTPUTS[0]} != "out" ]] && printf ':%s' "${OUTPUTS[0]}")" "$((${#PACKAGES[@]}-1))"
|
|
elif [[ ${#PACKAGES[@]} -gt $((_GUIX_MAXLIST+1)) ]]; then
|
|
printf "${_BLD}${_BLU}[${_NON}${_YLW}Guix${_NON}: ${_WHT}%s ${_NON}+ ${_PRP}%d ${_NON}pkgs${_BLD}${_BLU}] " "${PACKAGES[0]}$([[ ${OUTPUTS[0]} && ${OUTPUTS[0]} != "out" ]] && printf ':%s' "${OUTPUTS[0]}")" "$((${#PACKAGES[@]}-1))"
|
|
else
|
|
printf "${_BLD}${_BLU}[${_NON}${_YLW}Guix${_NON}: ${_WHT}%s${_BLD}${_BLU}] " "${PACKAGES[@]}$([[ ${OUTPUTS[0]} && ${OUTPUTS[0]} != "out" ]] && printf ':%s' "${OUTPUTS[0]}")"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
__prompt() {
|
|
# Get exit code (must be first)
|
|
local PLC=("${PIPESTATUS[@]}")
|
|
|
|
# Reset time when prompt was first displayed after command
|
|
# this contributes to the ~40 microsecond difference in $CMD_US and the actual time it took
|
|
if [[ "$INC_TIME" != 0 ]]; then
|
|
PROMPT_RT="$EPOCHREALTIME"
|
|
INC_TIME=0
|
|
fi
|
|
|
|
# *_RT may not be set
|
|
LAST_RT="${LAST_RT:-$EPOCHREALTIME}"
|
|
PROMPT_RT="${PROMPT_RT:-$EPOCHREALTIME}"
|
|
|
|
# Get relative times
|
|
|
|
# Remove decimal point, simulating multiplying by 1 million
|
|
PROMPT_RT1M="${PROMPT_RT/.}"
|
|
PROMPT_RT1M="${PROMPT_RT1M/,}"
|
|
LAST_RT1M="${LAST_RT/.}"
|
|
LAST_RT1M="${LAST_RT1M/,}"
|
|
|
|
((CMD_US=PROMPT_RT1M-LAST_RT1M))
|
|
|
|
CMD_TIME=0
|
|
|
|
# Divide by 1 million to get a more accurate difference
|
|
((CMD_TIME=CMD_US/1000000))
|
|
|
|
[[ ${#CMD_US} -lt 6 ]] || CMD_US="${CMD_US: -6}"
|
|
((CMD_US=10#$CMD_US))
|
|
|
|
# Set prompt sections
|
|
|
|
local SIG
|
|
local COL
|
|
local UHD
|
|
local TIME
|
|
local IND
|
|
local GUIX
|
|
|
|
# Text
|
|
|
|
# ssh detection and indicator
|
|
[[ "$SSH_CONNECTION" ]] && local SSH="$(__ssh) "
|
|
|
|
# [INT], [4], etc.
|
|
local RET
|
|
for RET in "${PLC[@]}"; do
|
|
if [[ $RET -gt 0 ]]; then
|
|
SIG="$(printf '%s[%s%s%s] ' "$_BLU" "$_RED" "$(__sig "${PLC[@]}")" "$_BLU")"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Guix shell environment
|
|
GUIX="$(__guix_env)"
|
|
|
|
# [user@homeserver:~]
|
|
COL="$([[ $UID == 0 ]] && printf '%s' "$_RED" || printf '%s' "$_YLW")"
|
|
UHD="${_BLD}${_BLU}[${COL}\u${_PRP}@${_CYN}\h${_PRP}:${_GRN}\w${_BLU}]"
|
|
|
|
# 2y 351d 12m 43s 382969μs
|
|
TIME="${_YLW}$(__get_cmd_time)"
|
|
|
|
# Random colored $ or #
|
|
_RAND256="\[\033[38;2;$((RANDOM%256));$((RANDOM%256));$((RANDOM%256))m\]"
|
|
IND="${_RAND256}\\$"
|
|
|
|
# Set the prompt
|
|
PS1="${_NON}${SSH}${GUIX}${SIG}${UHD} ${TIME} ${IND} ${_NON}"
|
|
}
|
|
|
|
PROMPT_COMMAND=__prompt |