Skip to content

Instantly share code, notes, and snippets.

@micalevisk
Last active December 9, 2018 23:56
Show Gist options
  • Save micalevisk/fa6b92556796cb84b6946538f1c2515c to your computer and use it in GitHub Desktop.
Save micalevisk/fa6b92556796cb84b6946538f1c2515c to your computer and use it in GitHub Desktop.
Duas abordagens para detecção de setas em Shell Script
#!/bin/bash
## solution1: $ sh arrow_key.sh
## solution2: $ sh arrow_key.sh 2 [-v]
: '
a d e f m o u ASCII
61 64 65 66 6D 6F 75 HEX
HEX ASCII
0a \n or \s
1b 5b 41 \033[A # Up arrow
1b 5b 42 \033[B # Down arrow
1b 5b 43 \033[C # Right arrow
1b 5b 44 \033[D # Left arrow
1b 5b 32 7e \033[2~ # insert key
1b 5b 33 7e \033[3~ # delete key
1b 5b 35 7e \033[5~ # page up key
1b 5b 36 7e \033[6~ # page down key
| | |
| | +------ ASCII A, B, C, D, 2, 3, 5 and 6
| +--------- ASCII [
+------------ ASCII ESC
'
## --------------------------------------------------------- ##
bind_arrow_up() { printf "\033[41m Up \033[0m\n"; }
bind_arrow_down() { printf "\033[45m Down \033[0m\n"; }
bind_arrow_right() { printf "\033[43m Right \033[0m\n"; }
bind_arrow_left() { printf "\033[44m Left \033[0m\n"; }
bind_esc() { printf "\033[32m Esc \033[0m\n"; }
bind_blank() { printf "\033[35m Enter or Space \033[0m\n"; }
bind_insert() { printf "\033[32m insert \033[0m\n"; } #-
bind_delete() { printf "\033[31m delete \033[0m\n"; } #-
## --------------------------------------------------------- ##
## (c) http://github.com/micalevisk
## estratégia: um-dois
## quantidade de leituras: 3
## problemas: não entende setas pressionadas, apenas clicadas
function solution1 {
while read -rsn1 ui ##§
do
case "$ui" in
$'\x1b') ## Handle ESC sequence.
read -rsn2 -t 0.1 key ##§
# od -tx1 <<< "$key"
[ "${key:0:1}" != '[' ] && bind_esc || {
case "${key:1:1}" in
'A') bind_arrow_up ;;
'B') bind_arrow_down ;;
'C') bind_arrow_right ;;
'D') bind_arrow_left ;;
'2') bind_insert ;;
'3') bind_delete ;;
esac
}
# Flush "stdin" with 0.1 sec timeout.
read -rsn5 -t 0.1 ;; ##§
$'') bind_blank ;;
*) #printf "other... quiting\n"; break;;
od -tx1 <<< "$ui"; break;;
esac
done
}
## (c) https://unix.stackexchange.com/questions/179191
## estratégia: um-um-um
## quantidade de leituras: 4
## problemas: delay perceptível; não entende setas pressionadas, apenas clicadas, nem cliques rápidos
function solution2 {
while read -rsn1 ui ##§
do
printf "~~~~~~~~~~~~~~~~~1\n" 1>&3
hexdump -C <<< "$ui" 1>&3
case "$ui" in
$'\x1b') ## Handle ESC sequence.
## Flush read. We account for sequences for Fx keys as well. 6 should suffice far more then enough.
read -rsn1 -t 0.1 tmp ##§
printf "_________________2\n" 1>&3
hexdump -C <<< "$tmp" 1>&3
if [ "$tmp" == "[" ]
then
read -rsn1 -t 0.1 tmp ##§
printf "_________________3\n" 1>&3
hexdump -C <<< "$tmp" 1>&3
case "$tmp" in
'A') bind_arrow_up ;;
'B') bind_arrow_down ;;
'C') bind_arrow_right ;;
'D') bind_arrow_left ;;
'2') bind_insert ;;
'3') bind_delete ;;
esac
elif [ -z "$tmp" ]
then
bind_esc
fi
# Flush "stdin" with 0.1 sec timeout.
read -rsn5 -t 0.1 ;; ##§
$'') bind_blank ;;
## Other one byte (char) cases. Here only quit.
*) printf "other... quiting\n"; break;;
esac
done
}
exec 3>/dev/null # não verboso
[ "$2" == "-v" ] && exec 3>&2 # verboso (para debug)
printf "Press an arrow key...\n\n"
[ "$1" == 2 ] && solution2 || solution1
@micalevisk
Copy link
Author

demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment