introduce --verbosity flag rather than mixed logging settings; correct color misnaming to ANSI convention; added sanity-check; simplified hello-world; created FZF_USER_INPUT to replace the confusing FZF_HEAD and FZF_TAIL
This commit is contained in:
		| @@ -2,22 +2,22 @@ __BLACK='\033[0;30m' | ||||
| __DARK_GRAY='\033[1;30m' | ||||
| 
 | ||||
| __RED='\033[0;31m' | ||||
| __LIGHT_RED='\033[1;31m' | ||||
| __BRIGHT_RED='\033[1;31m' | ||||
| 
 | ||||
| __GREEN='\033[0;32m' | ||||
| __LIGHT_GREEN='\033[1;32m' | ||||
| __BRIGHT_GREEN='\033[1;32m' | ||||
| 
 | ||||
| __ORANGE='\033[0;33m' | ||||
| __YELLOW='\033[1;33m' | ||||
| __YELLOW='\033[0;33m' | ||||
| __BRIGHT_YELLOW='\033[1;33m' | ||||
| 
 | ||||
| __BLUE='\033[1;34m' | ||||
| __DARK_BLUE='\033[0;34m' | ||||
| __BLUE='\033[0;34m' | ||||
| __BRIGHT_BLUE='\033[1;34m' | ||||
| 
 | ||||
| __PURPLE='\033[1;35m' | ||||
| __DARK_PURPLE='\033[0;35m' | ||||
| __MAGENTA='\033[0;35m' | ||||
| __BRIGHT_MAGENTA='\033[1;35m' | ||||
| 
 | ||||
| __CYAN='\033[1;36m' | ||||
| __DARK_CYAN='\033[0;36m' | ||||
| __CYAN='\033[0;36m' | ||||
| __BRIGHT_CYAN='\033[1;36m' | ||||
| 
 | ||||
| __WHITE='\033[1;37m' | ||||
| __LIGHT_GRAY='\033[0;37m' | ||||
| @@ -27,17 +27,17 @@ __COLOR_RESET='\033[0m' | ||||
| __GET_RANDOM_COLOR() { | ||||
| 	local COLORS=( | ||||
| 		$__RED | ||||
| 		$__LIGHT_RED | ||||
| 		$__BRIGHT_RED | ||||
| 		$__GREEN | ||||
| 		$__LIGHT_GREEN | ||||
| 		$__ORANGE | ||||
| 		$__BRIGHT_GREEN | ||||
| 		$__YELLOW | ||||
| 		$__BRIGHT_YELLOW | ||||
| 		$__BLUE | ||||
| 		$__DARK_BLUE | ||||
| 		$__PURPLE | ||||
| 		$__DARK_PURPLE | ||||
| 		$__BRIGHT_BLUE | ||||
| 		$__MAGENTA | ||||
| 		$__BRIGHT_MAGENTA | ||||
| 		$__CYAN | ||||
| 		$__DARK_CYAN | ||||
| 		$__BRIGHT_CYAN | ||||
| 		$__WHITE | ||||
| 	) | ||||
| 	print "$__COLOR_RESET${COLORS[$(shuf -i 1-${#COLORS[@]} -n 1)]}" | ||||
|   | ||||
| @@ -1,13 +1,14 @@ | ||||
| __CHECK_DEPENDENCIES() { | ||||
| 	local DEP ERROR=0 | ||||
| 	local DEP ERRORS=0 | ||||
| 	local SCWRYPTS_LOG_LEVEL=1 | ||||
| 	[ ! $E ] && E=ERROR | ||||
| 
 | ||||
| 	DEPENDENCIES=($(echo $DEPENDENCIES | sed 's/ \+/\n/g' | sort -u)) | ||||
| 
 | ||||
| 	for DEP in ${DEPENDENCIES[@]}; do __CHECK_DEPENDENCY $DEP || ((ERROR+=1)); done | ||||
| 	__CHECK_COREUTILS || ((ERROR+=$?)) | ||||
| 	for DEP in ${DEPENDENCIES[@]}; do __CHECK_DEPENDENCY $DEP || ((ERRORS+=1)); done | ||||
| 	__CHECK_COREUTILS || ((ERRORS+=$?)) | ||||
| 
 | ||||
| 	return $ERROR | ||||
| 	return $ERRORS | ||||
| } | ||||
| 
 | ||||
| __CHECK_DEPENDENCY() { | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| __CHECK_REQUIRED_ENV() { | ||||
| 	local SCWRYPTS_LOG_LEVEL=1 | ||||
| 	local VAR ERROR=0 | ||||
| 	REQUIRED_ENV=($(echo $REQUIRED_ENV | sed 's/\s\+/\n/g' | sort -u)) | ||||
| 	for VAR in ${REQUIRED_ENV[@]}; do __CHECK_ENV_VAR $VAR || ((ERROR+=1)); done | ||||
|   | ||||
							
								
								
									
										57
									
								
								zsh/lib/utils/io.fzf.zsh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								zsh/lib/utils/io.fzf.zsh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| FZF() { | ||||
| 	[ $CI ] && FAIL 1 'currently in CI, but FZF requires user input' | ||||
| 
 | ||||
| 	local FZF_ARGS=() | ||||
| 
 | ||||
| 	FZF_ARGS+=(-i) | ||||
| 	FZF_ARGS+=(--ansi) | ||||
| 	FZF_ARGS+=(--bind=ctrl-c:cancel) | ||||
| 	FZF_ARGS+=(--height=50%) | ||||
| 	FZF_ARGS+=(--layout=reverse) | ||||
| 
 | ||||
| 	local SELECTION=$(fzf ${FZF_ARGS[@]} --prompt "$1 : " ${@:2}) | ||||
| 	PROMPT "$1" | ||||
| 
 | ||||
| 	[ $BE_QUIET ] || { | ||||
| 		[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $SELECTION >&2 | ||||
| 	} | ||||
| 	echo $SELECTION | ||||
| 	[ $SELECTION ] | ||||
| } | ||||
| 
 | ||||
| FZF_USER_INPUT() { # allow user to type custom answers; reconfirm if ambiguous with select | ||||
| 	local FZF_OUTPUT=$(BE_QUIET=1 FZF $@ --print-query | sed '/^$/d' | sort -u) | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $FZF_OUTPUT | head -n1 >&2 | ||||
| 	[ ! $FZF_OUTPUT ] && return 1 | ||||
| 
 | ||||
| 	[[ $(echo "$FZF_OUTPUT" | wc -l) -eq 1 ]] \ | ||||
| 		&& { echo "$FZF_OUTPUT"; return 0; } | ||||
| 
 | ||||
| 	local FZF_OUTPUT=$( | ||||
| 		echo "$FZF_OUTPUT" \ | ||||
| 			| sed "1s/\$/^$(printf "$__LIGHT_GRAY\\033[3m")<- what you typed$(printf $__COLOR_RESET)/" \ | ||||
| 			| sed "2s/\$/^$(printf "$__LIGHT_GRAY\\033[3m")<- what you selected$(printf $__COLOR_RESET)/" \ | ||||
| 			| column -ts '^' \ | ||||
| 			| BE_QUIET=1 FZF "$@ (clarify)" \ | ||||
| 		) | ||||
| 
 | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $FZF_OUTPUT >&2 | ||||
| 	FZF_OUTPUT=$(echo $FZF_OUTPUT | sed 's/\s\+<- what you .*$//') | ||||
| 	echo $FZF_OUTPUT | ||||
| 	[ $FZF_OUTPUT ] | ||||
| } | ||||
| 
 | ||||
| ##################################################################### | ||||
| ### vvv DEPRECATED vvv ############################################## | ||||
| ##################################################################### | ||||
| 
 | ||||
| FZF_HEAD() {  # prefer user input over selected | ||||
| 	WARNING 'FZF_HEAD is deprecated; please switch to FZF_USER_INPUT (drop-in fix!)' | ||||
| 	FZF $@ --print-query | sed '/^$/d' | head -n1; | ||||
| } | ||||
| FZF_TAIL() {  # prefer selected over user input | ||||
| 	WARNING 'FZF_TAIL is deprecated; please switch to FZF_USER_INPUT (drop-in fix!)' | ||||
| 	FZF $@ --print-query | sed '/^$/d' | tail -n1; | ||||
| } | ||||
| 
 | ||||
| ##################################################################### | ||||
							
								
								
									
										38
									
								
								zsh/lib/utils/io.print.zsh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								zsh/lib/utils/io.print.zsh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| PRINT() { | ||||
| 	local MESSAGE | ||||
| 	local LAST_LINE_END='\n' | ||||
| 	local STDERR=1 | ||||
| 	local STDOUT=0 | ||||
| 
 | ||||
| 	local LTRIM=1 | ||||
| 	while [[ $# -gt 0 ]] | ||||
| 	do | ||||
| 		case $1 in | ||||
| 			-n | --no-trim-tabs ) LTRIM=0 ;; | ||||
| 			-x | --no-line-end  ) LAST_LINE_END='' ;; | ||||
| 			-o | --use-stdout   ) STDOUT=1; STDERR=0 ;; | ||||
| 			* ) MESSAGE+="$(echo $1) " ;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 	done | ||||
| 
 | ||||
| 	MESSAGE="$(echo "$MESSAGE" | sed 's/%/%%/g')" | ||||
| 
 | ||||
| 	local STYLED_MESSAGE="$({ | ||||
| 		printf "${COLOR}" | ||||
| 		while IFS='' read line | ||||
| 		do | ||||
| 			[[ $PREFIX =~ ^[[:space:]]\+$ ]] && printf '\n' | ||||
| 
 | ||||
| 			printf "${PREFIX} : $(echo "$line" | sed 's/^	\+//; s/ \+$//')" | ||||
| 
 | ||||
| 			PREFIX=$(echo $PREFIX | sed 's/./ /g') | ||||
| 		done <<< $MESSAGE | ||||
| 	})" | ||||
| 	STYLED_MESSAGE="${COLOR}$(echo "$STYLED_MESSAGE" | sed 's/%/%%/g')${__COLOR_RESET}${LAST_LINE_END}" | ||||
| 
 | ||||
| 	[[ $STDERR -eq 1 ]] && printf $STYLED_MESSAGE >&2 | ||||
| 	[[ $STDOUT -eq 1 ]] && printf $STYLED_MESSAGE | ||||
| 
 | ||||
| 	return 0 | ||||
| } | ||||
							
								
								
									
										65
									
								
								zsh/lib/utils/io.usage.zsh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								zsh/lib/utils/io.usage.zsh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| USAGE() { # formatter for USAGE variable | ||||
| 	[ ! $USAGE ] && return 0 | ||||
| 	local USAGE_LINE=$(echo $USAGE | grep -i '^[	]*usage *:' | sed 's/^[		]*//') | ||||
| 
 | ||||
| 	[ $USAGE__usage ] && echo $USAGE_LINE | grep -q 'usage: -' \ | ||||
| 		&& USAGE_LINE=$(echo $USAGE_LINE | sed "s/usage: -/usage: $USAGE__usage/") | ||||
| 
 | ||||
| 	[ $__SCWRYPT ] \ | ||||
| 		&& USAGE_LINE=$( | ||||
| 			echo $USAGE_LINE \ | ||||
| 				| sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \ | ||||
| 				| sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \ | ||||
| 			) | ||||
| 
 | ||||
| 	local THE_REST=$(echo $USAGE | grep -vi '^[		]*usage *:' ) | ||||
| 
 | ||||
| 	local DYNAMIC_USAGE_ELEMENT | ||||
| 	# | ||||
| 	# create dynamic usage elements (like 'args') by defining USAGE__<element> | ||||
| 	# then using the syntax "<element>: -" in your USAGE variable | ||||
| 	# | ||||
| 	# e.g. | ||||
| 	# | ||||
| 	# USAGE__args=" | ||||
| 	#	subcommand arg 1   arg 1 description | ||||
| 	#   subcommand arg 2   some other description | ||||
| 	# " | ||||
| 	# | ||||
| 	# USAGE=" | ||||
| 	# usage: some-command [...args...] | ||||
| 	# | ||||
| 	# args: - | ||||
| 	#   -h, --help   some arguments are applicable everywhere | ||||
| 	# " | ||||
| 	# | ||||
| 	for DYNAMIC_USAGE_ELEMENT in $(echo $THE_REST | sed -n 's/^\([^:]*\): -$/\1/p') | ||||
| 	do | ||||
| 		DYNAMIC_USAGE_ELEMENT_TEXT=$(eval echo '$USAGE__'$DYNAMIC_USAGE_ELEMENT) | ||||
| 		#[ $DYNAMIC_USAGE_ELEMENT_TEXT ] || continue | ||||
| 
 | ||||
| 
 | ||||
| 		case $DYNAMIC_USAGE_ELEMENT in | ||||
| 			description ) | ||||
| 				DYNAMIC_USAGE_ELEMENT_TEXT=$(echo "$DYNAMIC_USAGE_ELEMENT_TEXT" | perl -p0e 's/^[\n\s]+//') | ||||
| 			DYNAMIC_USAGE_ELEMENT_TEXT="$__YELLOW\\033[03m$DYNAMIC_USAGE_ELEMENT_TEXT\\033[0m" | ||||
| 				;; | ||||
| 			* ) | ||||
| 			DYNAMIC_USAGE_ELEMENT_TEXT=$(echo $DYNAMIC_USAGE_ELEMENT_TEXT | sed 's/[^	]/  &/') | ||||
| 				;; | ||||
| 		esac | ||||
| 
 | ||||
| 		THE_REST=$(echo $THE_REST | perl -pe "s$DYNAMIC_USAGE_ELEMENT: -$DYNAMIC_USAGE_ELEMENT:\n$DYNAMIC_USAGE_ELEMENT_TEXT\n\n") | ||||
| 	done | ||||
| 
 | ||||
| 	# allow for dynamic 'description: -' but delete the 'description:' header line | ||||
| 	THE_REST=$(echo $THE_REST | sed '/^[		]*description:$/d') | ||||
| 
 | ||||
| 	echo "$__BLUE$USAGE_LINE$__COLOR_RESET\n\n$THE_REST" \ | ||||
| 		| sed "s/^\t\+//; s/\s\+$//; s/^\\s*$//;" \ | ||||
| 		| sed '/./,$!d; :a; /^\n*$/{$d;N;ba;};' \ | ||||
| 		| perl -p0e 's/\n{2,}/\n\n/g' \ | ||||
| 		| perl -p0e 's/:\n{2,}/:\n/g' \ | ||||
| 		| perl -p0e 's/([a-z]+:)\n([a-z]+:)/\2/g' \ | ||||
| 		>&2 | ||||
| } | ||||
| @@ -1,216 +1,115 @@ | ||||
| PRINT() { | ||||
| 	local MESSAGE | ||||
| 	local LAST_LINE_END='\n' | ||||
| 	local STDERR=1 | ||||
| 	local STDOUT=0 | ||||
| 
 | ||||
| 	local LTRIM=1 | ||||
| 	while [[ $# -gt 0 ]] | ||||
| 	do | ||||
| 		case $1 in | ||||
| 			-n | --no-trim-tabs ) LTRIM=0 ;; | ||||
| 			-x | --no-line-end  ) LAST_LINE_END='' ;; | ||||
| 			-o | --use-stdout   ) STDOUT=1; STDERR=0 ;; | ||||
| 			* ) MESSAGE+="$(echo $1) " ;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 	done | ||||
| 
 | ||||
| 	MESSAGE="$(echo "$MESSAGE" | sed 's/%/%%/g')" | ||||
| 
 | ||||
| 	local STYLED_MESSAGE="$({ | ||||
| 		printf "${COLOR}" | ||||
| 		while IFS='' read line | ||||
| 		do | ||||
| 			[[ $PREFIX =~ ^[[:space:]]\+$ ]] && printf '\n' | ||||
| 
 | ||||
| 			printf "${PREFIX} : $(echo "$line" | sed 's/^	\+//; s/ \+$//')" | ||||
| 
 | ||||
| 			PREFIX=$(echo $PREFIX | sed 's/./ /g') | ||||
| 		done <<< $MESSAGE | ||||
| 	})" | ||||
| 	STYLED_MESSAGE="${COLOR}$(echo "$STYLED_MESSAGE" | sed 's/%/%%/g')${__COLOR_RESET}${LAST_LINE_END}" | ||||
| 
 | ||||
| 	[[ $STDERR -eq 1 ]] && printf $STYLED_MESSAGE >&2 | ||||
| 	[[ $STDOUT -eq 1 ]] && printf $STYLED_MESSAGE | ||||
| 
 | ||||
| 	return 0 | ||||
| } | ||||
| ##################################################################### | ||||
| ### basic colorized print messages ################################## | ||||
| ##################################################################### | ||||
| 
 | ||||
| source "${0:a:h}/io.print.zsh" | ||||
| [ ! $ERRORS ] && ERRORS=0 | ||||
| ERROR()    { PREFIX="ERROR    ✖" COLOR=$__RED    PRINT "$@"; ((ERRORS+=1)); } | ||||
| SUCCESS()  { PREFIX="SUCCESS  ✔" COLOR=$__GREEN  PRINT "$@"; } | ||||
| WARNING()  { PREFIX="WARNING  " COLOR=$__ORANGE PRINT "$@"; } | ||||
| STATUS()   { PREFIX="STATUS    " COLOR=$__BLUE   PRINT "$@"; } | ||||
| REMINDER() { PREFIX="REMINDER " COLOR=$__PURPLE PRINT "$@"; } | ||||
| INFO()     { PREFIX="INFO     ℹ" COLOR=$__WHITE  PRINT "$@"; } | ||||
| 
 | ||||
| PROMPT() { | ||||
| 	PREFIX="PROMPT   " COLOR=$__CYAN PRINT "$@" | ||||
| 	PREFIX="USER     ⌨" COLOR=$__CYAN PRINT '' --no-line-end | ||||
| } | ||||
| 
 | ||||
| FAIL()  { ERROR "${@:2}"; exit $1; } | ||||
| ABORT() { FAIL 69 'user abort'; } | ||||
| 
 | ||||
| CHECK_ERRORS() { | ||||
| 	local FAIL_OUT=1 | ||||
| 	local DISPLAY_USAGE=1 | ||||
| 
 | ||||
| 	while [[ $# -gt 0 ]] | ||||
| 	do | ||||
| 		case $1 in | ||||
| 			--no-fail  ) FAIL_OUT=0 ;; | ||||
| 			--no-usage ) DISPLAY_USAGE=0 ;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 	done | ||||
| 
 | ||||
| 	[ ! $ERRORS ] && ERRORS=0 | ||||
| 	[[ $ERRORS -eq 0 ]] && return 0 | ||||
| 
 | ||||
| 	[[ $DISPLAY_USAGE -eq 1 ]] && USAGE | ||||
| 
 | ||||
| 	[[ $FAIL_OUT -eq 1 ]] && exit $ERRORS | ||||
| 
 | ||||
| ERROR() {  # command encountered an error | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ | ||||
| 		&& PREFIX="ERROR    ✖" COLOR=$__RED            PRINT "$@" | ||||
| 	((ERRORS+=1)) | ||||
| 	return $ERRORS | ||||
| } | ||||
| 
 | ||||
| USAGE() { # formatter for USAGE variable | ||||
| 	[ ! $USAGE ] && return 0 | ||||
| 	local USAGE_LINE=$(echo $USAGE | grep -i '^[	]*usage *:' | sed 's/^[		]*//') | ||||
| SUCCESS() {  # command completed successfully | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ | ||||
| 		&& PREFIX="SUCCESS  ✔" COLOR=$__GREEN          PRINT "$@" | ||||
| } | ||||
| 
 | ||||
| 	[ $USAGE__usage ] && echo $USAGE_LINE | grep -q 'usage: -' \ | ||||
| 		&& USAGE_LINE=$(echo $USAGE_LINE | sed "s/usage: -/usage: $USAGE__usage/") | ||||
| REMINDER() {  # include sysadmin reminder or other important notice to users | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ | ||||
| 		&& PREFIX="REMINDER " COLOR=$__BRIGHT_MAGENTA PRINT "$@" | ||||
| } | ||||
| 
 | ||||
| 	[ $__SCWRYPT ] \ | ||||
| 		&& USAGE_LINE=$( | ||||
| 			echo $USAGE_LINE \ | ||||
| 				| sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \ | ||||
| 				| sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \ | ||||
| 			) | ||||
| STATUS() {  # general status updates (prefer this to generic 'echo') | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] \ | ||||
| 		&& PREFIX="STATUS    " COLOR=$__BLUE           PRINT "$@" | ||||
| } | ||||
| 
 | ||||
| 	local THE_REST=$(echo $USAGE | grep -vi '^[		]*usage *:' ) | ||||
| WARNING() {  # warning-level messages; not errors | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 3 ]] \ | ||||
| 		&& PREFIX="WARNING  " COLOR=$__YELLOW         PRINT "$@" | ||||
| } | ||||
| 
 | ||||
| 	local DYNAMIC_USAGE_ELEMENT | ||||
| 	# | ||||
| 	# create dynamic usage elements (like 'args') by defining USAGE__<element> | ||||
| 	# then using the syntax "<element>: -" in your USAGE variable | ||||
| 	# | ||||
| 	# e.g. | ||||
| 	# | ||||
| 	# USAGE__args=" | ||||
| 	#	subcommand arg 1   arg 1 description | ||||
| 	#   subcommand arg 2   some other description | ||||
| 	# " | ||||
| 	# | ||||
| 	# USAGE=" | ||||
| 	# usage: some-command [...args...] | ||||
| 	# | ||||
| 	# args: - | ||||
| 	#   -h, --help   some arguments are applicable everywhere | ||||
| 	# " | ||||
| 	# | ||||
| 	for DYNAMIC_USAGE_ELEMENT in $(echo $THE_REST | sed -n 's/^\([^:]*\): -$/\1/p') | ||||
| DEBUG() {  # helpful during development or (sparingly) to help others' development | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -gt 4 ]] \ | ||||
| 		&& PREFIX="DEBUG    ℹ" COLOR=$__WHITE          PRINT "$@" | ||||
| } | ||||
| 
 | ||||
| PROMPT() {  # you probably want to use yN or INPUT from below | ||||
| 	[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ | ||||
| 		&& PREFIX="PROMPT   " COLOR=$__CYAN PRINT "$@" \ | ||||
| 		&& PREFIX="USER     ⌨" COLOR=$__BRIGHT_CYAN PRINT '' --no-line-end \ | ||||
| 		; | ||||
| } | ||||
| 
 | ||||
| FAIL()  { SCWRYPTS_LOG_LEVEL=1 ERROR "${@:2}"; exit $1; } | ||||
| ABORT() { FAIL 69 'user abort'; } | ||||
| 
 | ||||
| ##################################################################### | ||||
| ### check for reported errors and format USAGE contents ############# | ||||
| ##################################################################### | ||||
| 
 | ||||
| CHECK_ERRORS() { | ||||
| 	local FAIL_OUT=true | ||||
| 	local DISPLAY_USAGE=true | ||||
| 
 | ||||
| 	[ ! $ERRORS ] && ERRORS=0 | ||||
| 
 | ||||
| 	while [[ $# -gt 0 ]] | ||||
| 	do | ||||
| 		DYNAMIC_USAGE_ELEMENT_TEXT=$(eval echo '$USAGE__'$DYNAMIC_USAGE_ELEMENT) | ||||
| 		case $1 in | ||||
| 			--fail    ) FAIL_OUT=true  ;; | ||||
| 			--no-fail ) FAIL_OUT=false ;; | ||||
| 
 | ||||
| 		[[ ! $DYNAMIC_USAGE_ELEMENT =~ ^description$ ]] \ | ||||
| 			&& DYNAMIC_USAGE_ELEMENT_TEXT=$(echo $DYNAMIC_USAGE_ELEMENT_TEXT | sed 's/[^	]/  &/') | ||||
| 
 | ||||
| 		THE_REST=$(echo $THE_REST | perl -pe "s/$DYNAMIC_USAGE_ELEMENT: -/$DYNAMIC_USAGE_ELEMENT:\n$DYNAMIC_USAGE_ELEMENT_TEXT\n\n/") | ||||
| 			--usage    ) DISPLAY_USAGE=true  ;; | ||||
| 			--no-usage ) DISPLAY_USAGE=false ;; | ||||
| 		esac | ||||
| 		shift 1 | ||||
| 	done | ||||
| 
 | ||||
| 	# allow for dynamic 'description: -' but delete the 'description:' header line | ||||
| 	THE_REST=$(echo $THE_REST | sed '/^[		]*description:$/d') | ||||
| 	[[ $ERRORS -eq 0 ]] && return 0 | ||||
| 
 | ||||
| 	echo "$__DARK_BLUE$USAGE_LINE$__COLOR_RESET\n\n$THE_REST" \ | ||||
| 		| sed "s/^\t\+//; s/\s\+$//; s/^\\s*$//;" \ | ||||
| 		| sed '/./,$!d; :a; /^\n*$/{$d;N;ba;};' \ | ||||
| 		| perl -p0e 's/\n{2,}/\n\n/g' \ | ||||
| 		| perl -p0e 's/:\n{2,}/:\n/g' \ | ||||
| 		>&2 | ||||
| 	[[ $DISPLAY_USAGE =~ true ]] && USAGE | ||||
| 
 | ||||
| 	[[ $FAIL_OUT =~ true ]] && exit $ERRORS || return $ERRORS | ||||
| } | ||||
| 
 | ||||
| INPUT() { | ||||
| 	PROMPT "${@:2}" | ||||
| 	READ $1 | ||||
| 	local VALUE=$(eval echo '$'$1) | ||||
| 	[ $VALUE ] | ||||
| } | ||||
| source "${0:a:h}/io.usage.zsh" | ||||
| 
 | ||||
| Yn() { | ||||
| ##################################################################### | ||||
| ### facilitate user prompt and input ################################ | ||||
| ##################################################################### | ||||
| 
 | ||||
| Yn() {  # ask a yes-or-no question (default yes) | ||||
| 	PROMPT "$@ [Yn]" | ||||
| 	[ $CI ] && { echo y; return 0; } | ||||
| 	[ $CI ] && { echo y >&2; return 0; } | ||||
| 	[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; } | ||||
| 
 | ||||
| 	local Yn; READ -k Yn; echo >&2 | ||||
| 	[[ $Yn =~ [nN] ]] && return 1 || return 0 | ||||
| } | ||||
| 
 | ||||
| yN() { | ||||
| yN() {  # ask a yes-or-no question (default no) | ||||
| 	PROMPT "$@ [yN]" | ||||
| 	[ $CI ] && { echo y; return 0; } | ||||
| 	[ $CI ] && { echo y >&2; return 0; } | ||||
| 	[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; } | ||||
| 
 | ||||
| 	local yN; READ -k yN; echo >&2 | ||||
| 	[[ $yN =~ [yY] ]] && return 0 || return 1 | ||||
| } | ||||
| 
 | ||||
| CAPTURE() { | ||||
| 	[ ! $USAGE ] && USAGE=" | ||||
| 	usage: stdout-varname stderr-varname [...cmd and args...] | ||||
| 
 | ||||
| 	captures stdout and stderr on separate variables for a command | ||||
| 	" | ||||
| 	{ | ||||
| 		IFS=$'\n' read -r -d '' $2; | ||||
| 		IFS=$'\n' read -r -d '' $1; | ||||
| 	} < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1) | ||||
| INPUT() {  # read a single line of user input | ||||
| 	PROMPT "${@:2}" | ||||
| 	READ $1 | ||||
| 	local VALUE=$(eval echo '$'$1) | ||||
| 	[ $VALUE ] | ||||
| } | ||||
| 
 | ||||
| ##################################################################### | ||||
| source "${0:a:h}/io.fzf.zsh"  # allow user to select from a list of inputs | ||||
| 
 | ||||
| GETSUDO() { | ||||
| 	echo "\\033[1;36mPROMPT    : checking sudo password...\\033[0m" >&2 | ||||
| 	sudo echo hi >/dev/null 2>&1 </dev/tty \ | ||||
| 		&& SUCCESS '...authenticated!' \ | ||||
| 		|| { ERROR 'failed :c'; return 1; } | ||||
| } | ||||
| 
 | ||||
| LESS() { less -R $@ </dev/tty >/dev/tty; } | ||||
| 
 | ||||
| FZF()      { | ||||
| 	[ $CI ] && { | ||||
| 		ERROR 'currently in CI, but FZF requires user input' | ||||
| 		exit 1 | ||||
| 	} | ||||
| 
 | ||||
| 	local FZF_ARGS=() | ||||
| 
 | ||||
| 	FZF_ARGS+=(-i) | ||||
| 	FZF_ARGS+=(--ansi) | ||||
| 	FZF_ARGS+=(--bind=ctrl-c:cancel) | ||||
| 	FZF_ARGS+=(--height=50%) | ||||
| 	FZF_ARGS+=(--layout=reverse) | ||||
| 
 | ||||
| 	local SELECTION=$(fzf ${FZF_ARGS[@]} --layout=reverse --prompt "$1 : " ${@:2}) | ||||
| 	PROMPT "$1" | ||||
| 	echo $SELECTION >&2 | ||||
| 	echo $SELECTION | ||||
| } | ||||
| FZF_HEAD() { FZF $@ --print-query | sed '/^$/d' | head -n1; } # prefer user input over selected | ||||
| FZF_TAIL() { FZF $@ --print-query | sed '/^$/d' | tail -n1; } # prefer selected over user input | ||||
| 
 | ||||
| READ()  { | ||||
| 	[ $CI ] && { | ||||
| 		INFO 'currently in CI, skipping READ' | ||||
| 		return 0 | ||||
| 	} | ||||
| 	read $@ </dev/tty | ||||
| } | ||||
| 
 | ||||
| EDIT() { | ||||
| EDIT() {  # edit a file in user's preferred editor | ||||
| 	[ $CI ] && { | ||||
| 		INFO 'currently in CI, skipping EDIT' | ||||
| 		return 0 | ||||
| @@ -221,6 +120,12 @@ EDIT() { | ||||
| 	SUCCESS "finished editing '$1'!" | ||||
| } | ||||
| 
 | ||||
| ##################################################################### | ||||
| ### basic commands with tricky states or default requirements ####### | ||||
| ##################################################################### | ||||
| 
 | ||||
| LESS() { less -R $@ </dev/tty >/dev/tty; } | ||||
| 
 | ||||
| YQ() { | ||||
| 	yq --version | grep -q mikefarah || { | ||||
| 		yq $@ | ||||
| @@ -229,3 +134,37 @@ YQ() { | ||||
| 
 | ||||
| 	yq eval '... comments=""' | yq $@ | ||||
| } | ||||
| 
 | ||||
| ##################################################################### | ||||
| ### other i/o utilities ############################################# | ||||
| ##################################################################### | ||||
| 
 | ||||
| CAPTURE() { | ||||
| 	[ ! $USAGE ] && USAGE=" | ||||
| 		usage: stdout-varname stderr-varname [...cmd and args...] | ||||
| 
 | ||||
| 		captures stdout and stderr on separate variables for a command | ||||
| 	" | ||||
| 	{ | ||||
| 		IFS=$'\n' read -r -d '' $2; | ||||
| 		IFS=$'\n' read -r -d '' $1; | ||||
| 	} < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| GETSUDO() { | ||||
| 	echo "\\033[1;36mPROMPT    : checking sudo password...\\033[0m" >&2 | ||||
| 	sudo echo hi >/dev/null 2>&1 </dev/tty \ | ||||
| 		&& SUCCESS '...authenticated!' \ | ||||
| 		|| { ERROR 'failed :c'; return 1; } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| READ()  { | ||||
| 	[ $CI ] && { | ||||
| 		INFO 'currently in CI, skipping READ' | ||||
| 		return 0 | ||||
| 	} | ||||
| 	read $@ </dev/tty | ||||
| } | ||||
| 
 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user