init
This commit is contained in:
commit
ed521e2e3c
46
README.md
Normal file
46
README.md
Normal file
@ -0,0 +1,46 @@
|
||||
# tui.sh
|
||||
|
||||
Text-based User Interface library for POSIX compliant shells.
|
||||
|
||||
```shell
|
||||
#!/bin/sh
|
||||
|
||||
. ./tui.sh
|
||||
|
||||
# Code...
|
||||
```
|
||||
|
||||
See examples.
|
||||
|
||||
# Known issues
|
||||
|
||||
Currently I've no idea how to force `tput` correctly clear screen on sclroll.
|
||||
|
||||
- [ ] Cant use `tui_select` in subshell e.g. `selected=$(tui_select 1 2 3)`
|
||||
- [ ] `tui_select` doesn't work properly on terminal scroll.
|
||||
- [ ] `tui_spin -r` doesn't work properly on terminal scroll.
|
||||
|
||||
# Roadmap
|
||||
|
||||
Functions list may be changed later.
|
||||
|
||||
- [ ] `tui_msg` message box with OK button
|
||||
- [x] `tui_select` menu
|
||||
- [ ] `tui_checklist` menu with multiple choice
|
||||
- [ ] `tui_confirm` confirmation menu (yes/no)
|
||||
- [ ] `tui_input` text input
|
||||
- [ ] `tui_password` password input
|
||||
- [x] `tui_spin` spinner
|
||||
- [ ] `tui_progress` progress bar
|
||||
- [ ] `tui_print` print formatted text
|
||||
- [ ] `tui_splitscr` split screen
|
||||
- [x] `tui_termsize` get actual terminal size, set COLUMNS and LINES
|
||||
- [x] `tui_curpos` get current terminal cursor position
|
||||
- [x] `tui_readchar` read characters from keyboard
|
||||
- [x] `tui_readkey` read keyboard codes
|
||||
- [x] `tui_optval` cli argument parser
|
||||
- [x] `tui_fallback` fallback to default terminal settings
|
||||
|
||||
# License
|
||||
|
||||
Licensed under The Unlicense, see UNLICENSE.
|
24
UNLICENSE
Normal file
24
UNLICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
6
examples/curpos
Normal file
6
examples/curpos
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ../tui.sh
|
||||
|
||||
pos="$(tui_curpos)"
|
||||
printf 'Cursor position: COLUMN=%s LINE=%s\n' "${pos% *}" "${pos#* }"
|
9
examples/readchar
Normal file
9
examples/readchar
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ../tui.sh
|
||||
|
||||
num="${1:-1}"
|
||||
printf 'Usage: readchar NUMBER\n'
|
||||
printf 'Input characters (number=%s):\n' "$num"
|
||||
tui_readchar -n "$num" VAR
|
||||
echo Characters: $VAR
|
7
examples/readkey
Normal file
7
examples/readkey
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ../tui.sh
|
||||
|
||||
printf 'Press any key. Key will printed below.\n'
|
||||
tui_readkey KEY
|
||||
printf 'Key pressed: %s\n' "$KEY"
|
17
examples/readkey_2
Normal file
17
examples/readkey_2
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ../tui.sh
|
||||
|
||||
printf 'Press arrow keys, q to quit.\n'
|
||||
|
||||
while true; do
|
||||
tui_readkey KEY
|
||||
case "$KEY" in
|
||||
Up) printf 'Move UP\n';;
|
||||
Down) printf 'Move DOWN\n';;
|
||||
Left) printf 'Move LEFT\n';;
|
||||
Right) printf 'Move RIGHT\n';;
|
||||
q|Q) break;;
|
||||
*) :
|
||||
esac
|
||||
done
|
5
examples/select
Normal file
5
examples/select
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ../tui.sh
|
||||
|
||||
tui_select First Second 'Another one'
|
18
examples/spin
Normal file
18
examples/spin
Normal file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ../tui.sh
|
||||
|
||||
tui_spin \
|
||||
-t 'Sleeping...' \
|
||||
-m '\033[32;1m✓ Waked up!\033[0m' \
|
||||
-- sleep 3
|
||||
|
||||
tui_spin -r \
|
||||
-t 'Ping Google...' \
|
||||
-m '\033[32;1m✓ Ping Google OK!\033[0m' \
|
||||
-- ping -c 3 google.com
|
||||
|
||||
tui_spin \
|
||||
-t 'Search *bash* files...' \
|
||||
-m '\033[32;1m✓ Search *bash* files OK!\033[0m' \
|
||||
-- find ~ -name "*bash*"
|
435
tui.sh
Normal file
435
tui.sh
Normal file
@ -0,0 +1,435 @@
|
||||
#!/bin/sh
|
||||
|
||||
# _____ _ _ ___ ____ _ _
|
||||
# |_ _| | | |_ _| / ___|| | | |
|
||||
# | | | | | || | \___ \| |_| |
|
||||
# | | | |_| || | _ ___) | _ |
|
||||
# |_| \___/|___(_)____/|_| |_|
|
||||
#
|
||||
# tui.sh - Text-based User Interface library for POSIX compliant shells.
|
||||
#
|
||||
# Depends on: libcurses (tput), GNU coreutils.
|
||||
# Tested on: bash, dash.
|
||||
#
|
||||
# FUNCTIONS
|
||||
#
|
||||
# tui_msg message box with OK button
|
||||
# tui_select menu
|
||||
# tui_checklist menu with multiple choice
|
||||
# tui_confirm confirmation menu (yes/no)
|
||||
# tui_input text input
|
||||
# tui_password password input
|
||||
# tui_spin spinner
|
||||
# tui_progress progress bar
|
||||
# tui_print print formatted text
|
||||
# tui_splitscr split screen
|
||||
# tui_termsize get actual terminal size, set COLUMNS and LINES
|
||||
# tui_curpos get current terminal cursor position
|
||||
# tui_readchar read characters from keyboard
|
||||
# tui_readkey read keyboard codes
|
||||
# tui_optval cli argument parser
|
||||
# tui_fallback fallback to default terminal settings
|
||||
|
||||
# ------------------------------------------------------------------------- #
|
||||
# Helper functions #
|
||||
# ------------------------------------------------------------------------- #
|
||||
|
||||
tui_termsize()
|
||||
{
|
||||
# Return actual terminal size "COLUMNS LINES"
|
||||
# Set COLUMNS and LINES variables.
|
||||
|
||||
COLUMNS="${COLUMNS:-$(tput cols)}"
|
||||
LINES="${LINES:-$(tput lines)}"
|
||||
|
||||
printf '%s %s\n' "$COLUMNS" "$LINES"
|
||||
}
|
||||
|
||||
tui_curpos()
|
||||
{
|
||||
# Return current cursor position "COLUMN LINE" e.g. "0 27"
|
||||
# Ref: https://stackoverflow.com/a/12341833
|
||||
|
||||
exec < /dev/tty
|
||||
oldstty="$(stty -g)"
|
||||
stty raw -echo min 0
|
||||
tput u7 > /dev/tty
|
||||
sleep .02
|
||||
IFS=';' read -r _row _col
|
||||
stty "$oldstty"
|
||||
|
||||
_row="$(expr $(expr substr $_row 3 99) - 1)" # Strip leading escape off
|
||||
_col="$(expr ${_col%R} - 1)" # Strip trailing 'R' off
|
||||
|
||||
printf '%s %s\n' "$_col" "$_row"
|
||||
}
|
||||
|
||||
tui_fallback()
|
||||
{
|
||||
# Handle script interruption
|
||||
# Usage: trap tui_fallback <signal>
|
||||
# See trap(1), signal.h(0P)
|
||||
|
||||
tput rmcup # restore screen content
|
||||
tput rc # restore cursor position
|
||||
tput ed # clear screen after cursor position
|
||||
tput cnorm # show cursor
|
||||
}
|
||||
|
||||
tui_optval()
|
||||
{
|
||||
# GNU-style CLI options parser.
|
||||
# Parses `--opt VAL` and `--opt=VAL` options..
|
||||
# Usage: tui_optval "$1" "$2"
|
||||
# Sets variables:
|
||||
# _opt - option name
|
||||
# _val - option's value
|
||||
# _sft - value for shift
|
||||
|
||||
_opt="${1%%=*}"; _val="${1#*=}"; _shift=1
|
||||
|
||||
if [ "$_opt" = "$_val" ]; then
|
||||
if [ -n "$2" ] && [ "${2#${2%%?}}" != "-" ]; then
|
||||
_val="$2"; _shift=2
|
||||
else
|
||||
unset _val
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$_val" ]; then
|
||||
echo "Missing argument for option $_opt" >&2; exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
tui_readchar()
|
||||
{
|
||||
# Read number of chars into variable
|
||||
# Usage: tui_readchar [-n <num>] <var>
|
||||
# Options:
|
||||
# -n <num> number of characters [default: 1]
|
||||
# Arguments:
|
||||
# <var> variable where the character will be stored
|
||||
|
||||
unset _num
|
||||
while [ "$#" -ne 0 ]; do
|
||||
case "$1" in
|
||||
-n)
|
||||
tui_optval "$1" "$2"
|
||||
_num="$_val"
|
||||
shift "$_shift"
|
||||
;;
|
||||
-*)
|
||||
printf 'tui_readchar: illegal option %s\n' "$OPT" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
_var="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
_num="${_num:-1}"
|
||||
if [ -z "$_var" ]; then
|
||||
echo 'tui_readchar: missing argument <var>' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
stty -icanon -echo
|
||||
eval "$_var=\$(dd bs=1 count="$_num" 2>/dev/null)"
|
||||
stty icanon echo
|
||||
}
|
||||
|
||||
tui_readkey()
|
||||
{
|
||||
# Read keys from keyboard and return key name or octodecimal keycode
|
||||
# Usage: tui_readkey <var>
|
||||
# Arguments:
|
||||
# <var> variable where the key code will be stored
|
||||
# Ref: https://www.unix.com/shell-programming-and-scripting/\
|
||||
# 110380-using-arrow-keys-shell-scripts.html
|
||||
|
||||
tty_save="$(stty -g)"
|
||||
_var="$1"
|
||||
|
||||
if [ -z "$_var" ]; then
|
||||
echo 'tui_readkey: missing argument <var>' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_odx() {
|
||||
od -t o1 | awk '{ for (i=2; i<=NF; i++)
|
||||
printf("%s%s", i==2 ? "" : " ", $i)
|
||||
exit }'
|
||||
}
|
||||
|
||||
get_ascii() {
|
||||
# Return ASCII character by octodecimal code
|
||||
if [ "$1" = '000' ]; then
|
||||
_oct=0
|
||||
else
|
||||
_oct="$(echo $1 | sed 's/^00//g;s/^0//g')"
|
||||
fi
|
||||
_i=0 # iterator
|
||||
# "_F" below is filler for decimal numbering
|
||||
for ascii in NUL SOH STX ETX EOT ENQ ACK BEL \
|
||||
_F _F BS HT LF VT FF CR SO SI \
|
||||
_F _F DLE DC1 DC2 DC3 DC4 NAK SYN ETB \
|
||||
_F _F CAN EM SUB ESC FS GS RS US \
|
||||
_F _F Space '!' '"' '#' '$' '%' '&' "'" \
|
||||
_F _F '(' ')' '*' '+' ',' '-' '.' '/' \
|
||||
_F _F 0 1 2 3 4 5 6 7 \
|
||||
_F _F 8 9 ':' ';' '<' = '>' '?' \
|
||||
_F _F _F _F _F _F _F _F _F _F _F _F _F _F \
|
||||
_F _F _F _F _F _F _F _F '@' \
|
||||
A B C D E F G _F _F \
|
||||
H I J K L M N O _F _F \
|
||||
P Q R S T U V W _F _F X Y Z \
|
||||
'[' '\' ']' '^' '_' _F _F '`' \
|
||||
a b c d e f g _F _F h i j k l m n o _F _F \
|
||||
p q r s t u v w _F _F x y z \
|
||||
'{' '|' '}' '~' DEL; do
|
||||
if [ "$_i" -eq "$_oct" ]; then
|
||||
echo "$ascii"
|
||||
fi
|
||||
_i=$(( _i + 1 ))
|
||||
done
|
||||
}
|
||||
|
||||
# Grab terminal capabilities
|
||||
# Docs: "https://www.gnu.org/software/termutils/manual/termutils-2.0/\
|
||||
# html_chapter/tput_1.html"
|
||||
tty_cuu1=$(tput cuu1 2>&1 | get_odx) # Up arrow
|
||||
tty_kcuu1=$(tput kcuu1 2>&1 | get_odx)
|
||||
tty_cud1=$(tput cud1 2>&1 | get_odx) # Down arrow
|
||||
tty_kcud1=$(tput kcud1 2>&1 | get_odx)
|
||||
tty_cub1=$(tput cub1 2>&1 | get_odx) # Left arrow
|
||||
tty_kcub1=$(tput kcud1 2>&1 | get_odx)
|
||||
tty_cuf1=$(tput cuf1 2>&1 | get_odx) # Right arrow
|
||||
tty_kcuf1=$(tput kcud1 2>&1 | get_odx)
|
||||
tty_ent=$(echo | get_odx) # Enter
|
||||
tty_kent=$(tput kent 2>&1 | get_odx)
|
||||
tty_bs=$(echo -n "\b" | get_odx) # BackSpace
|
||||
tty_kbs=$(tput kbs 2>&1 | get_odx)
|
||||
tty_khome=$(tput khome 2>&1 | get_odx) # Home
|
||||
tty_kend=$(tput kend 2>&1 | get_odx) # End
|
||||
tty_kpp=$(tput kpp 2>&1 | get_odx) # Page Up
|
||||
tty_knp=$(tput knp 2>&1 | get_odx) # Page Down
|
||||
tty_kf1=$(tput kf1 2>&1 | get_odx) # Functional keys (1-12)
|
||||
tty_kf2=$(tput kf2 2>&1 | get_odx)
|
||||
tty_kf3=$(tput kf3 2>&1 | get_odx)
|
||||
tty_kf4=$(tput kf4 2>&1 | get_odx)
|
||||
tty_kf5=$(tput kf5 2>&1 | get_odx)
|
||||
tty_kf6=$(tput kf6 2>&1 | get_odx)
|
||||
tty_kf7=$(tput kf7 2>&1 | get_odx)
|
||||
tty_kf8=$(tput kf8 2>&1 | get_odx)
|
||||
tty_kf9=$(tput kf9 2>&1 | get_odx)
|
||||
tty_kf10=$(tput kf10 2>&1 | get_odx)
|
||||
tty_kf11=$(tput kf11 2>&1 | get_odx)
|
||||
tty_kf12=$(tput kf12 2>&1 | get_odx)
|
||||
|
||||
# Some terminals (e.g. PuTTY) send the wrong code for certain arrow keys
|
||||
if [ "$tty_cuu1" = "033 133 101" -o "$tty_kcuu1" = "033 133 101" ]; then
|
||||
tty_cudx="033 133 102"
|
||||
tty_cufx="033 133 103"
|
||||
tty_cubx="033 133 104"
|
||||
fi
|
||||
|
||||
stty cs8 -icanon -echo min 10 time 1
|
||||
stty intr '' susp ''
|
||||
|
||||
trap "stty "$tty_save"; exit" INT HUP TERM
|
||||
|
||||
keypress=$(dd bs=10 count=1 2> /dev/null | get_odx)
|
||||
|
||||
stty "$tty_save"
|
||||
unset _key
|
||||
case "$keypress" in
|
||||
"$tty_ent"|"$tty_kent") _key=Enter;;
|
||||
"$tty_bs"|"$tty_kbs") _key=BackSpace;;
|
||||
"$tty_cuu1"|"$tty_kcuu1") _key=Up;;
|
||||
"$tty_cud1"|"$tty_kcud1"|"$tty_cudx") _key=Down;;
|
||||
"$tty_cub1"|"$tty_kcub1"|"$tty_cubx") _key=Left;;
|
||||
"$tty_cuf1"|"$tty_kcuf1"|"$tty_cufx") _key=Right;;
|
||||
"$tty_khome") _key=Home;;
|
||||
"$tty_kend") _key=End;;
|
||||
"$tty_kpp") _key=Page_Up;;
|
||||
"$tty_knp") _key=Page_Down;;
|
||||
"$tty_kf1") _key=F1;;
|
||||
"$tty_kf2") _key=F2;;
|
||||
"$tty_kf3") _key=F3;;
|
||||
"$tty_kf4") _key=F4;;
|
||||
"$tty_kf5") _key=F5;;
|
||||
"$tty_kf6") _key=F6;;
|
||||
"$tty_kf7") _key=F7;;
|
||||
"$tty_kf8") _key=F8;;
|
||||
"$tty_kf9") _key=F9;;
|
||||
"$tty_kf10") _key=F10;;
|
||||
"$tty_kf11") _key=F11;;
|
||||
"$tty_kf12") _key=F12;;
|
||||
*)
|
||||
# Display other keys and codes
|
||||
if echo "$keypress" | grep '^[0-9][0-9][0-9]$' >/dev/null 2>&1; then
|
||||
_key="$(get_ascii "$keypress")"
|
||||
else
|
||||
_key="$keypress"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
stty -icanon -echo
|
||||
eval "$_var=\$_key"
|
||||
stty icanon echo
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------- #
|
||||
# General functions #
|
||||
# ------------------------------------------------------------------------- #
|
||||
|
||||
tui_spin()
|
||||
{
|
||||
# Show spinner until command runs
|
||||
# Usage: tui_spin [options] -- <command>
|
||||
# Options:
|
||||
# -c <char> character set for spinner
|
||||
# -t <title> title to display
|
||||
# -m <text> the message that will be shown after the process ends
|
||||
# -o (1|2|12|21) send command output to /dev/null (1=stdout, 2=stderr).
|
||||
# -r restore cursor after process ends. Removes screen
|
||||
# content created after startup cursor position.
|
||||
# -- end of options.
|
||||
# Arguments:
|
||||
# <command> command to execute
|
||||
#
|
||||
# To prevent data loss with '-o' option use this syntax:
|
||||
# tui_spin 'command > file.tmp'
|
||||
#
|
||||
# Defaul spinner character set is '4/8' (see below). You can set
|
||||
# ASCII safe character set e.g. \-/|
|
||||
# Some Unicode character sets (Braille Pattern Dots):
|
||||
# 3/6: ⠇⠋⠙⠸⠴⠦
|
||||
# 5/6: ⠟⠻⠽⠾⠷⠯
|
||||
# 4/8: ⡇⠏⠛⠹⢸⣰⣤⣆
|
||||
# 7/8: ⣷⣯⣟⡿⢿⣻⣽⣾
|
||||
|
||||
unset chars title fin_message devnull restore_cursor
|
||||
while [ "$#" -ne 0 ]; do
|
||||
case "$1" in
|
||||
-c) tui_optval "$1" "$2"; chars="$_val"; shift "$_shift";;
|
||||
-t) tui_optval "$1" "$2"; title="$_val"; shift "$_shift";;
|
||||
-m) tui_optval "$1" "$2"; fin_message="$_val"; shift "$_shift";;
|
||||
-o) tui_optval "$1" "$2"; devnull="$_val"; shift "$_shift";;
|
||||
-r) restore_cursor=1; shift;;
|
||||
--) shift; set -- "$@"; break;; # end of options
|
||||
-*) printf 'tui_spin: illegal option %s\n' "$1" >&2
|
||||
exit 1;;
|
||||
*) shift;;
|
||||
esac
|
||||
done
|
||||
|
||||
tput sc # save cursor position
|
||||
tput civis # hide cursor
|
||||
|
||||
chars="${chars:-⡇⠏⠛⠹⢸⣰⣤⣆}"
|
||||
|
||||
# Run command in background and save PID
|
||||
case "$devnull" in
|
||||
1)
|
||||
"$@" 1>/dev/null &
|
||||
pid="$!"
|
||||
;;
|
||||
2)
|
||||
"$@" 2>/dev/null &
|
||||
pid="$!"
|
||||
;;
|
||||
12|21)
|
||||
"$@" >/dev/null 2>&1 &
|
||||
pid="$!"
|
||||
;;
|
||||
*)
|
||||
"$@" &
|
||||
pid="$!"
|
||||
;;
|
||||
esac
|
||||
|
||||
while [ -d /proc/"$pid" ]; do # spin while command is running
|
||||
index=0
|
||||
for char in $(echo "$chars" | grep -o .); do
|
||||
sleep .06
|
||||
printf '%s %b\r' "$char" "$title"
|
||||
done
|
||||
done
|
||||
|
||||
if [ -n "$restore_cursor" ]; then
|
||||
tput rc # restore cursor position
|
||||
tput ed # clear screen after cursor position
|
||||
fi
|
||||
|
||||
if [ -n "$fin_message" ]; then
|
||||
tput el # erase line
|
||||
printf '%b\n' "$fin_message"
|
||||
fi
|
||||
|
||||
tput cnorm # show cursor
|
||||
}
|
||||
|
||||
tui_select()
|
||||
{
|
||||
# Interactive menu.
|
||||
# Usage: tui_select <items>...
|
||||
|
||||
tput civis # hide cursor
|
||||
|
||||
pos=1 # `cursor` position
|
||||
|
||||
while true; do
|
||||
tput ed
|
||||
tput sc
|
||||
|
||||
# Print menu items
|
||||
index=1 # $@ array index
|
||||
while [ "$((index - 1))" -ne "$#" ]; do
|
||||
if [ "$index" -eq "$pos" ]; then
|
||||
eval "printf '> \033[7m%s\033[27m\n' \"\${${index}}\""
|
||||
else
|
||||
eval "printf ' %s\n' \"\${${index}}\""
|
||||
fi
|
||||
index="$(( index + 1 ))"
|
||||
done
|
||||
|
||||
# Read input
|
||||
tui_readkey _input
|
||||
|
||||
case "$_input" in
|
||||
'['|[hHjJ]|Left|Up|'033 133 132')
|
||||
# move up
|
||||
pos="$(( pos - 1 ))"
|
||||
;;
|
||||
']'|[kKlL]|Down|Right|HT)
|
||||
# move down
|
||||
pos="$(( pos + 1 ))"
|
||||
;;
|
||||
Enter)
|
||||
# select
|
||||
selected="$(eval "echo \${${pos}}")"
|
||||
break
|
||||
;;
|
||||
ETX)
|
||||
# ctrl+c
|
||||
break
|
||||
;;
|
||||
*)
|
||||
:
|
||||
esac
|
||||
|
||||
# Jump to last item if user press "up" when pos=1 and vice versa
|
||||
if [ "$pos" -lt 1 ]; then pos="$#"; fi
|
||||
if [ "$pos" -gt "$#" ]; then pos=1; fi
|
||||
|
||||
tput rc
|
||||
done
|
||||
|
||||
tput cnorm # show cursor
|
||||
|
||||
echo "$selected" # print output
|
||||
}
|
Loading…
Reference in New Issue
Block a user