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