diff --git a/assets/spinny/spinny.sh b/assets/spinny/spinny.sh new file mode 100755 index 00000000..9e83f7a7 --- /dev/null +++ b/assets/spinny/spinny.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +declare __spinny__spinner_pid + +declare -a __spinny__frames=() + +spinny::start() { + tput civis + spinny::_spinner & + __spinny__spinner_pid=$! +} + +spinny::stop() { + [[ -z "$__spinny__spinner_pid" ]] && return 0 + + kill -9 "$__spinny__spinner_pid" + # Use conditional to avoid exiting the program immediatly + wait "$__spinny__spinner_pid" 2>/dev/null || true +} + +spinny::_spinner() { + local delay=${SPINNY_DELAY:-0.3} + spinny::_load_frames + spinny::_pad_frames + while : + do + for frame in "${__spinny__frames[@]}" + do + # After rendering each frame the cursor is reset to + # the previous position so that the next frame can + # overwrite it + tput sc + printf "%b" "$frame" + tput rc + sleep "$delay" + done + done +} + +spinny::_pad_frames() { + # Frames with different lengths need to be padded + # for a smooth animation. We calculate the maximum + # size of all frames and pad all smaller ones with + # white space. + local max_length + max_length=$(spinny::_max_framelength) + local array_length=${#__spinny__frames[@]} + for (( i=0; c max)) && max=$len + done + echo "$max" +} + +spinny::_load_frames() { + # Load custom frames if any or fall back on the default animation + if [[ -z $SPINNY_FRAMES ]]; then + __spinny__frames=(- "\\" "|" /) + else + __spinny__frames=("${SPINNY_FRAMES[@]}") + fi +} + +spinny::_finish(){ + # Make sure to remove variables and make the cursor visible again + unset __spinny__spinner_pid + unset __spinny__frames + tput cnorm +} + +trap spinny::_finish EXIT + +