#!/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 ))