shell/helpers/io.sh

364 lines
11 KiB
Bash
Raw Normal View History

2025-01-17 19:07:28 +08:00
#!/usr/bin/env bash
2024-11-24 21:13:37 +08:00
########################################################
# Simple and fancy input & output
########################################################
2025-01-16 14:23:46 +08:00
which tput > /dev/null 2>&1 && [[ $(tput -T$TERM colors) -gt 8 ]] && CAN_USE_COLORS=1 || CAN_USE_COLORS=0
USE_COLORS=${USE_COLORS:-$CAN_USE_COLORS}
[ $USE_COLORS = 1 ] && IINFO="( i )" || IINFO=''
[ $USE_COLORS = 1 ] && INOTE="( * )" || INOTE=''
[ $USE_COLORS = 1 ] && IWARN="( # )" || IWARN=''
[ $USE_COLORS = 1 ] && IERROR="( ! )" || IERROR=''
[ $USE_COLORS = 1 ] && IFATAL="( @ )" || IFATAL=''
[ $USE_COLORS = 1 ] && ISUCCESS="( ! )" || ISUCCESS=''
[ $USE_COLORS = 1 ] && IASK="( ? )" || IASK=''
[ $USE_COLORS = 1 ] && IDEBUG="(DBG)" || IDEBUG=''
[ $USE_COLORS = 1 ] && IVRB="( + )" || IVRB=''
[ $USE_COLORS = 1 ] && BOLD="\e[1m" || BOLD=''
[ $USE_COLORS = 1 ] && DIM="\e[2m" || DIM=''
[ $USE_COLORS = 1 ] && NOTBOLD="\e[22m" || NOTBOLD='' # sometimes \e[21m
[ $USE_COLORS = 1 ] && NOTDIM="\e[22m" || NOTDIM=''
[ $USE_COLORS = 1 ] && NORMAL="\e[20m" || NORMAL=''
[ $USE_COLORS = 1 ] && RESET="\e[0m" || RESET=''
[ $USE_COLORS = 1 ] && FRESET="\e[39m" || FRESET=''
[ $USE_COLORS = 1 ] && FBLACK="\e[30m" || FBLACK=''
[ $USE_COLORS = 1 ] && FWHITE="\e[97m" || FWHITE=''
[ $USE_COLORS = 1 ] && FRED="\e[31m" || FRED=''
[ $USE_COLORS = 1 ] && FGREEN="\e[32m" || FGREEN=''
[ $USE_COLORS = 1 ] && FYELLOW="\e[33m" || FYELLOW=''
[ $USE_COLORS = 1 ] && FBLUE="\e[34m" || FBLUE=''
[ $USE_COLORS = 1 ] && FLRED="\e[91m" || FLRED=''
[ $USE_COLORS = 1 ] && FLGREEN="\e[92m" || FLGREEN=''
[ $USE_COLORS = 1 ] && FLYELLOW="\e[93m" || FLYELLOW=''
[ $USE_COLORS = 1 ] && FLBLUE="\e[94m" || FLBLUE=''
[ $USE_COLORS = 1 ] && BRESET="\e[49m" || BRESET=''
[ $USE_COLORS = 1 ] && BBLACK="\e[40m" || BBLACK=''
[ $USE_COLORS = 1 ] && BWHITE="\e[107m" || BWHITE=''
[ $USE_COLORS = 1 ] && BRED="\e[41m" || BRED=''
[ $USE_COLORS = 1 ] && BGREEN="\e[42m" || BGREEN=''
[ $USE_COLORS = 1 ] && BYELLOW="\e[43m" || BYELLOW=''
[ $USE_COLORS = 1 ] && BBLUE="\e[44m" || BBLUE=''
[ $USE_COLORS = 1 ] && BLRED="\e[101m" || BLRED=''
[ $USE_COLORS = 1 ] && BLGREEN="\e[102m" || BLGREEN=''
[ $USE_COLORS = 1 ] && BLYELLOW="\e[103m" || BLYELLOW=''
[ $USE_COLORS = 1 ] && BLBLUE="\e[104m" || BLBLUE=''
2024-11-24 21:13:37 +08:00
dt() {
echo "[$(date +'%H:%M:%S')] "
}
ask() {
IFS= read -rp "$(print ${BOLD}${BBLUE}${FWHITE}${IASK}${BRESET}\ ${BOLD}$1 ): " $2
}
print() {
echo -e "$*${RESET}"
}
debug() {
if [ "$2" ]; then
print "${DIM}${BOLD}${RESET}${DIM}$(dt)${IDEBUG} ${FUNCNAME[1]:-?}():${BASH_LINENO:-?}\t$1 " >&2
else
print "${DIM}${BOLD}${RESET}${DIM}$(dt)${IDEBUG} $1 " >&2
fi
}
verbose() {
print "${BOLD}$(dt)${IVRB}${RESET}${FYELLOW} $1 "
}
info() {
print "${BOLD}$(dt)${FWHITE}${BLBLUE}${IINFO}${RESET}${FWHITE} $1 "
}
note() {
print "${BOLD}$(dt)${DIM}${FWHITE}${INOTE}${RESET} $1 "
}
success() {
print "${BOLD}$(dt)${BGREEN}${FWHITE}${ISUCCESS}${BRESET}$FGREEN $1 "
}
warn() {
print "${BOLD}$(dt)${BYELLOW}${FBLACK}${IWARN}${BRESET}${FYELLOW} Warning:${RESET} $1 "
}
error() {
print "${BOLD}$(dt)${BLRED}${FWHITE}${IERROR} Error: ${BRESET}${FLRED} $1 " >&2
}
fatal() {
print "${BOLD}$(dt)${BRED}${FWHITE}${IFATAL} FATAL: $1 " >&2
print_stacktrace
}
die() {
error "${1:-halted}"
exit ${2:-255}
}
# var='test var_dump'
# var_dump var
# debug 'test debug'
# verbose 'test verbose'
# info 'test info'
# note 'test note'
# success 'test success'
# warn 'test warn'
# error 'test error'
# fatal 'test fatal'
# die 'test die'
2025-01-16 14:23:46 +08:00
# experiments ==============================================================================
# https://unix.stackexchange.com/a/269085
# https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
# https://linuxcommand.org/lc3_adv_tput.php
# https://gist.github.com/dtmilano/4055d6df5b6e4ea87c5a72dc2d604193
# https://gist.github.com/nick3499/402a6d7dccd474f2bdb679f4311b1238
# https://gist.github.com/connorjan/2b02126868157c2b69f9aa0a052cdc86
# tput setaf 0
# echo "BLACK FOREGROUND"
# tput setaf 1
# echo "RED FOREGROUND"
# tput setaf 2
# echo "GREEN FOREGROUND"
# tput setaf 3
# echo "YELLOW FOREGROUND"
# tput setaf 4
# echo "BLUE FOREGROUND"
# tput setaf 5
# echo "MAGENTA FOREGROUND"
# tput setaf 6
# echo "CYAN FOREGROUND"
# tput setaf 7
# echo "WHITE FOREGROUND"
# tput reset
# ===========
# Text color - normal
# fgblack="$(tput setaf 0)" # Black
# fgred="$(tput setaf 1)" # Red
# fggreen="$(tput setaf 2)" # Green
# fgyellow="$(tput setaf 3)" # Yellow
# fgblue="$(tput setaf 4)" # Blue
# fgpurple="$(tput setaf 5)" # Purple
# fgcyan="$(tput setaf 6)" # Cyan
# fgwhite="$(tput setaf 7)" # White
# # Text color - bright
# bfgblack="$(tput setaf 8)" # Black
# bfgred="$(tput setaf 9)" # Red
# bfggreen="$(tput setaf 10)" # Green
# bfgyellow="$(tput setaf 11)" # Yellow
# bfgblue="$(tput setaf 12)" # Blue
# bfgpurple="$(tput setaf 13)" # Purple
# bfgcyan="$(tput setaf 14)" # Cyan
# bfgwhite="$(tput setaf 15)" # White
# # Background color - normal
# bgblack="$(tput setab 0)" # Black - Background
# bgred="$(tput setab 1)" # Red
# bggreen="$(tput setab 2)" # Green
# bgyellow="$(tput setab 3)" # Yellow
# bgblue="$(tput setab 4)" # Blue
# bgpurple="$(tput setab 5)" # Purple
# bgcyan="$(tput setab 6)" # Cyan
# bgwhite="$(tput setab 7)" # White
# # Background color - bright
# bbgblack="$(tput setab 8)" # Black - Background - Bright
# bbgred="$(tput setab 9)" # Red
# bbggreen="$(tput setab 10)" # Green
# bbgyellow="$(tput setab 11)" # Yellow
# bbgblue="$(tput setab 12)" # Blue
# bbgpurple="$(tput setab 13)" # Purple
# bbgcyan="$(tput setab 14)" # Cyan
# bbgwhite="$(tput setab 15)" # White
# # Other attributes
# normal="$(tput sgr0)" # text reset
# bold="$(tput bold)" # make bold
# underline="$(tput smul)" # underline
# nounderlin="$(tput rmul)" # remove underline
# mkblink="$(tput blink)" # make blink
# reverse="$(tput rev)" # reverse
# ===========
# tohex(){
# dec=$(($1%256)) ### input must be a number in range 0-255.
# if [ "$dec" -lt "16" ]; then
# bas=$(( dec%16 ))
# mul=128
# [ "$bas" -eq "7" ] && mul=192
# [ "$bas" -eq "8" ] && bas=7
# [ "$bas" -gt "8" ] && mul=255
# a="$(( (bas&1) *mul ))"
# b="$(( ((bas&2)>>1)*mul ))"
# c="$(( ((bas&4)>>2)*mul ))"
# printf 'dec= %3s basic= #%02x%02x%02x\n' "$dec" "$a" "$b" "$c"
# elif [ "$dec" -gt 15 ] && [ "$dec" -lt 232 ]; then
# b=$(( (dec-16)%6 )); b=$(( b==0?0: b*40 + 55 ))
# g=$(( (dec-16)/6%6)); g=$(( g==0?0: g*40 + 55 ))
# r=$(( (dec-16)/36 )); r=$(( r==0?0: r*40 + 55 ))
# printf 'dec= %3s color= #%02x%02x%02x\n' "$dec" "$r" "$g" "$b"
# else
# gray=$(( (dec-232)*10+8 ))
# printf 'dec= %3s gray= #%02x%02x%02x\n' "$dec" "$gray" "$gray" "$gray"
# fi
# }
# for i in $(seq 0 255); do
# tohex ${i}
# done
# ===========
# fromhex(){
# hex=${1#"#"}
# r=$(printf '0x%0.2s' "$hex")
# g=$(printf '0x%0.2s' ${hex#??})
# b=$(printf '0x%0.2s' ${hex#????})
# printf '%03d' "$(( (r<75?0:(r-35)/40)*6*6 +
# (g<75?0:(g-35)/40)*6 +
# (b<75?0:(b-35)/40) + 16 ))"
# }
# fromhex 00fc7b
# ===========
# mode2header(){
# #### For 16 Million colors use \e[0;38;2;R;G;Bm each RGB is {0..255}
# printf '\e[mR\n' # reset the colors.
# printf '\n\e[m%59s\n' "Some samples of colors for r;g;b. Each one may be 000..255"
# printf '\e[m%59s\n' "for the ansi option: \e[0;38;2;r;g;bm or \e[0;48;2;r;g;bm :"
# }
# mode2colors(){
# # foreground or background (only 3 or 4 are accepted)
# local fb="$1"
# [[ $fb != 3 ]] && fb=4
# local samples=(0 63 127 191 255)
# for r in "${samples[@]}"; do
# for g in "${samples[@]}"; do
# for b in "${samples[@]}"; do
# printf '\e[0;%s8;2;%s;%s;%sm%03d;%03d;%03d ' "$fb" "$r" "$g" "$b" "$r" "$g" "$b"
# done; printf '\e[m\n'
# done; printf '\e[m'
# done; printf '\e[mReset\n'
# }
# mode2header
# mode2colors 3
# mode2colors 4
# ===========
# printf '\e[48;5;%dm ' {0..255}; printf '\e[0m \n'
# for r in {200..255..5}; do
# fb=4
# g=1
# b=1
# printf '\e[0;%s8;2;%s;%s;%sm ' "$fb" "$r" "$g" "$b"
# done
# echo
# ===========
# color(){
# for c; do
# printf '\e[48;5;%dm%03d' $c $c
# done
# printf '\e[0m \n'
# }
# IFS=$' \t\n'
# color {0..15}
# for ((i=0;i<6;i++)); do
# color $(seq $((i*36+16)) $((i*36+51)))
# done
# color {232..255}
# ===========
# for ((i=0; i<256; i++)) ;do
# echo -n ' '
# tput setab $i
# tput setaf $(( ( (i>231&&i<244 ) || ( (i<17)&& (i%8<2)) ||
# (i>16&&i<232)&& ((i-16)%6 <(i<100?3:2) ) && ((i-16)%36<15) )?7:16))
# printf " C %03d " $i
# tput op
# (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
# printf "\n" ''
# done
# ===========
# echo "tput character test"
# echo "==================="
# echo
# tput bold; echo "This text has the bold attribute."; tput sgr0
# tput smul; echo "This text is underlined (smul)."; tput rmul
# # Most terminal emulators do not support blinking text (though xterm
# # does) because blinking text is considered to be in bad taste ;-)
# tput blink; echo "This text is blinking (blink)."; tput sgr0
# tput rev; echo "This text has the reverse attribute"; tput sgr0
# # Standout mode is reverse on many terminals, bold on others.
# tput smso; echo "This text is in standout mode (smso)."; tput rmso
# tput sgr0
# echo
# experiments ==============================================================================
# function delay_spinner(){
# ##
# ## Usage:
# ##
# ## $ long-running-command &
# ## $ delay_spinner " Please wait msg..."
# ##
# ## Spinner exists when long-running-command completes
# ##
# local PROGRESSTXT
# if [ ! "$1" ]; then
# PROGRESSTXT=" Please wait..."
# else
# PROGRESSTXT="$1"
# fi
# # visual progress marker function
# # http://stackoverflow.com/users/2869509/wizurd
# # vars
# local pid=$!
# local delay=0.1
# local spinstr='|/-\'
# echo -e "\n\n"
# while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
# local temp=${spinstr#?}
# printf "\r$PROGRESSTXT[%c] " "$spinstr"
# local spinstr=$temp${spinstr%"$temp"}
# sleep $delay
# printf "\b\b\b\b\b\b"
# done
# printf -- '\n\n'
# #
# # <-- end function ec2cli_spinner -->
# #
# }
# sleep 10 && echo 'test' &
# delay_spinner "Please wait msg..."