Created
March 11, 2017 00:30
-
-
Save NicholasRoge/2619a48fffd9e84534ac30c5f9e9d5e1 to your computer and use it in GitHub Desktop.
Forgive me father for I have sinned
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
source "$LIB_DIR/overload" | |
interact() | |
{ | |
local _flag= | |
if (( $# > 0 )) | |
then | |
_flag="$1" | |
else | |
_flag=true | |
fi | |
tput civis | |
stty -echo | |
while eval '$'"$_flag" | |
do | |
update | |
done | |
stty echo | |
tput cnorm | |
} | |
update() | |
{ | |
# intentionally empty | |
: | |
} | |
declare -A keys=() | |
keys[esc]=$'\c[' | |
keys[return]=$'\cM' | |
keys[ctrl-c]=$'\cC' | |
keys[space]=' ' | |
keys[array-up]=$'\c[[A' | |
keys[array-down]=$'\c[[B' | |
keys[arrow-right]=$'\c[[C' | |
keys[arrow-left]=$'\c[[D' | |
update:keys() | |
{ | |
if read -t 0.1 -rn1 | |
then | |
local seq=$REPLY | |
if [[ "$seq" == $'\c[' ]] | |
then | |
while read -t 0.1 -rn1 | |
do | |
seq="$seq$REPLY" | |
if [[ "$REPLY" == [a-zA-Z] ]] | |
then | |
break | |
fi | |
done | |
fi | |
key_pressed "$seq" | |
fi | |
} | |
key_pressed() | |
{ | |
# Intentionally empty | |
: | |
} | |
trap $'key_pressed \cC' SIGINT | |
overload key_pressed ${keys[ctrl-c]} 'exit' | |
overload -e update update:keys | |
timeouts=() | |
timeout() | |
{ | |
if [[ "$1" == '-r' ]] | |
then | |
local repeating=true | |
shift | |
else | |
local repeating=false | |
fi | |
duration=$1 | |
callable="$2" | |
local current_time=$(date +%s) | |
local timeout_time=$((current_time + duration)) | |
timeouts+=($timeout_time "$callable" $repeating $duration) | |
} | |
update:timeouts() | |
{ | |
local offset=0 | |
local offset_max=${#timeouts[@]} | |
while (( offset < offset_max )) | |
do | |
local current_time=$(date +%s) | |
local timeout_time=${timeouts[$offset]} | |
if (( current_time < timeout_time )) | |
then | |
((offset+=4)) | |
continue | |
fi | |
local callable=${timeouts[$((offset + 1))]} | |
eval "$callable" | |
local repeating=${timeouts[$((offset + 2))]} | |
if $repeating | |
then | |
timeouts[$offset]=$((current_time + ${timeouts[$((offset + 3))]})) | |
((offset+=4)) | |
else | |
unset timeouts[$offset] | |
unset timeouts[$offset] | |
unset timeouts[$offset] | |
unset timeouts[$offset] | |
((offset_max-=4)) | |
fi | |
done | |
} | |
overload -e update update:timeouts | |
latest_width= | |
latest_height= | |
update:termsize() | |
{ | |
local width=$(tput cols) | |
local height=$(tput lines) | |
if (( width != latest_width )) || (( height != latest_height )) | |
then | |
termsize_updated $width $height $latest_width $latest_height | |
latest_width=$width | |
latest_height=$height | |
fi | |
} | |
termsize_updated() | |
{ | |
# Intentionally empty | |
: | |
} | |
shopt -s checkwinsize | |
overload -e update update:termsize |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment