91 lines
2.4 KiB
Bash
Executable File
91 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
|
|
_help() {
|
|
SELF=$( basename "$0" )
|
|
echo "Read arrows keys up/down
|
|
|
|
Usage: $SELF [-c Char]
|
|
-c Char Print Char character at the start of line
|
|
|
|
Returns
|
|
100 - number of rows above start point
|
|
0 if ctrl-c or ESC pressed
|
|
|
|
"
|
|
exit
|
|
}
|
|
|
|
CHAR=""
|
|
for (( i=1; i<=$#; i++ )); do
|
|
value=${!i}
|
|
j=$(( i + 1 ))
|
|
[[ "$value" = "-h" ]] && _help
|
|
[[ "$value" = "--help" ]] && _help
|
|
[[ "$value" = "-c" ]] && { CHAR="${!j}"; ((i++)); continue; }
|
|
done
|
|
printf -v EMPTYCHAR "%-${#CHAR}s" " "
|
|
|
|
|
|
ESC=$( printf "\033")
|
|
cursor_blink_on() { printf "$ESC[?25h"; }
|
|
cursor_blink_off() { printf "$ESC[?25l"; }
|
|
cursor_to() { printf "$ESC[$1;${2:-1}H"; }
|
|
get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
|
|
get_screen_rows() { tput lines; }
|
|
key_input() { read -s -n1 key1 2>/dev/null >&2
|
|
read -s -n2 -t 0.1 key2 2>/dev/null >&2
|
|
if [[ $key1 = "" ]]; then echo enter; return; fi
|
|
if [[ $key1$key2 = $ESC[A ]]; then echo up; return; fi
|
|
if [[ $key1$key2 = $ESC[B ]]; then echo down; return; fi
|
|
if [[ -z "$key2" ]]; then
|
|
if [[ $key1 = $'\e' ]]; then echo esc; return; fi
|
|
fi
|
|
}
|
|
reset_display() {
|
|
cursor_blink_on; stty echo;
|
|
}
|
|
print_char() { printf -- "$CHAR\r"; }
|
|
print_empty() { if [[ -n "$CHAR" ]]; then printf "$EMPTYCHAR\r"; fi; }
|
|
|
|
startrow=`get_cursor_row`
|
|
trap "cursor_blink_on; stty echo; cursor_to $startrow; exit 1" 2
|
|
#trap "cursor_blink_on; stty echo; printf '\n'; exit 1" 2
|
|
if [[ -n "$CHAR" ]]; then
|
|
cursor_blink_off
|
|
fi
|
|
selected=0
|
|
while true; do
|
|
cursor_to $(( $startrow - $selected))
|
|
print_char
|
|
# user key control
|
|
case `key_input` in
|
|
enter) break;;
|
|
esc) reset_display; exit 1;;
|
|
up)
|
|
cursor_to $(( $startrow - $selected))
|
|
print_empty
|
|
((selected++));
|
|
# limit going top
|
|
;;
|
|
down)
|
|
cursor_to $(( $startrow - $selected))
|
|
print_empty
|
|
((selected--));
|
|
# limit going down
|
|
;;
|
|
esac
|
|
lastrow=`get_cursor_row`
|
|
if [ $(( $startrow - $selected )) -lt 1 ]; then
|
|
((selected--))
|
|
fi
|
|
if [ $(( startrow - $selected )) -gt `get_screen_rows` ]; then
|
|
((selected++))
|
|
fi
|
|
done
|
|
|
|
cursor_blink_on
|
|
cursor_to $startrow
|
|
|
|
exit $(( 100 - $selected ))
|