init
This commit is contained in:
287
lib/interact.bash
Normal file
287
lib/interact.bash
Normal file
@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env bash
|
||||
# _
|
||||
# | | _ _
|
||||
# | |____ _| |_ _____ ____ _____ ____ _| |_
|
||||
# | | _ (_ _) ___ |/ ___|____ |/ ___|_ _)
|
||||
# | | | | || |_| ____| | / ___ ( (___ | |_
|
||||
# |_|_| |_| \__)_____)_| \_____|\____) \__)
|
||||
#
|
||||
# Bash powered interactive interfaces.
|
||||
#
|
||||
# Interact is Bash functions library that implements some
|
||||
# interactive elements like menus, checkboxes and others.
|
||||
# You can use Interact instead of Whiptail and Dialog.
|
||||
# Interact depends only Bash native commands and basic utils.
|
||||
|
||||
menu() {
|
||||
# Interactive menu
|
||||
#
|
||||
# Return string SELECTED_ITEM from array.
|
||||
# Array must be passed as argument.
|
||||
#
|
||||
# Variables:
|
||||
# MENU_PROMPT -- string with prompt message;
|
||||
# MENU_INDENT -- string with intentation chars;
|
||||
# MENU_HELP -- string with help message.
|
||||
|
||||
local menu_items=("$@") # array of items
|
||||
local inp= # reset input
|
||||
local pos=0 # initial cursor position
|
||||
|
||||
tput smcup # save screen contents
|
||||
tput civis # hide cursor
|
||||
|
||||
while [[ ! "$inp" =~ [qQ] ]]; do
|
||||
clear # clear screen
|
||||
|
||||
if [ "$MENU_PROMPT" ]
|
||||
then echo -e "$MENU_PROMPT"
|
||||
else echo -e "Select item:\n"
|
||||
fi
|
||||
|
||||
# Print menu items
|
||||
for i in "${!menu_items[@]}"; do
|
||||
[ "$MENU_INDENT" ] && echo -en "$MENU_INDENT"
|
||||
# Highlight selected item (invert colors)
|
||||
if [ $i -eq $pos ]
|
||||
then echo -e "> \e[7m${menu_items[${i}]}\e[27m"
|
||||
else echo -e " ${menu_items[${i}]}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Print help text
|
||||
if [ ! "$MENU_HELP" ]; then
|
||||
tput cup $(tput lines) 0
|
||||
echo -en \
|
||||
"\e[7mUse HJKL or arrow keys to move, Enter to select, q to quit\e[27m"
|
||||
tput home
|
||||
else echo -e "$MENU_HELP"
|
||||
fi
|
||||
|
||||
# Read input (including arrow keys)
|
||||
inp=
|
||||
local escape_char=$(printf "\u1b")
|
||||
read -r -s -n 1 inp # get 1 character
|
||||
# Read 2 more chars
|
||||
if [[ $inp == $escape_char ]]; then read -r -s -n 2 inp; fi
|
||||
|
||||
case "$inp" in
|
||||
[[hHjJ]|'[A'|'[D' ) pos=$(( $pos - 1 )) ;; # move up
|
||||
[]kKlL]|'[B'|'[C' ) pos=$(( $pos + 1 )) ;; # move down
|
||||
'' ) SELECTED_ITEM="${menu_items[${pos}]}"; break ;; # enter
|
||||
esac
|
||||
|
||||
# Jump to last item if user press "up" when pos=0 and vice versa
|
||||
if [ $pos -lt 0 ]; then pos=$(( ${#menu_items[@]} - 1 )); fi
|
||||
if [ $pos -gt $(( ${#menu_items[@]} - 1 )) ]; then pos=0; fi
|
||||
done
|
||||
|
||||
tput rmcup # restore screen contents
|
||||
tput cnorm # show terminal cursor
|
||||
}
|
||||
|
||||
checklist() {
|
||||
# Interactive checklist
|
||||
#
|
||||
# Return string CHECKED_ITEMS from array.
|
||||
# Array must be passed as argument.
|
||||
#
|
||||
# Variables:
|
||||
# CHECK_PROMPT -- string with prompt message;
|
||||
# CHECK_INDENT -- string with intentation chars;
|
||||
# CHECK_HELP -- string with help message.
|
||||
|
||||
local checklist_items=("$@") # array of items
|
||||
local inp= # reset input
|
||||
local pos=0 # initial cursor position
|
||||
|
||||
tput smcup # save screen contents
|
||||
tput civis # hide terminal cursor
|
||||
|
||||
while [[ ! "$inp" =~ [qQ] ]]; do
|
||||
clear # clear screen
|
||||
|
||||
if [ "$CHECK_PROMPT" ]
|
||||
then echo -e "$CHECK_PROMPT"
|
||||
else echo -e "Check items:\n"
|
||||
fi
|
||||
|
||||
# Print menu items
|
||||
for i in "${!checklist_items[@]}"; do
|
||||
[ "$CHECK_INDENT" ] && echo -en "$CHECK_INDENT"
|
||||
|
||||
if [[ "${checked[@]}" =~ "${checklist_items[${i}]}" ]]
|
||||
then marker="[x] "
|
||||
else marker="[ ] "
|
||||
fi
|
||||
|
||||
# Highlight selected item (invert colors)
|
||||
if [ $i -eq $pos ]
|
||||
then echo -e "> \e[7m${marker}${checklist_items[${i}]}\e[27m"
|
||||
else echo -e " ${marker}${checklist_items[${i}]}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Print help text
|
||||
if [ ! "$CHECK_HELP" ]; then
|
||||
tput cup $(tput lines) 0
|
||||
echo -en \
|
||||
"\e[7mUse HJKL or arrow keys to move, Enter to check, q to quit\e[27m"
|
||||
tput home
|
||||
else echo -e "$CHECK_HELP"
|
||||
fi
|
||||
|
||||
# Read input (including arrow keys)
|
||||
inp=
|
||||
local escape_char=$(printf "\u1b")
|
||||
read -r -s -n 1 inp # get 1 character
|
||||
# Read 2 more chars
|
||||
if [[ $inp == $escape_char ]]; then read -r -s -n 2 inp; fi
|
||||
|
||||
case "$inp" in
|
||||
[[hHjJ]|'[A'|'[D' ) pos=$(( $pos - 1 )) ;; # move up
|
||||
[]kKlL]|'[B'|'[C' ) pos=$(( $pos + 1 )) ;; # move down
|
||||
'' )
|
||||
# Check / uncheck items
|
||||
if [[ "${checked[@]}" =~ "${checklist_items[${pos}]}" ]]
|
||||
then
|
||||
# Uncheck item
|
||||
checked=( "${checked[@]/${checklist_items[${pos}]}}" )
|
||||
else
|
||||
# Check new item
|
||||
checked+=("${checklist_items[${pos}]}")
|
||||
fi
|
||||
# Automove cursor
|
||||
[ $pos -lt $(( ${#checklist_items[@]} - 1 )) ] \
|
||||
&& pos=$(( $pos + 1 ));;
|
||||
esac
|
||||
|
||||
# Jump to last item if user press "up" when pos=0 and vice versa
|
||||
if [ $pos -lt 0 ]; then pos=$(( ${#checklist_items[@]} - 1 )); fi
|
||||
if [ $pos -gt $(( ${#checklist_items[@]} - 1 )) ]; then pos=0; fi
|
||||
done
|
||||
|
||||
# Remove blank items from array
|
||||
for item in "${checked[@]}"; do
|
||||
if [[ "$item" != "" ]]; then
|
||||
CHECKED_ITEMS+=("$item")
|
||||
fi
|
||||
done
|
||||
|
||||
clear # clear screen
|
||||
tput rmcup # restore screen contents
|
||||
tput cnorm # show terminal cursor
|
||||
}
|
||||
|
||||
messagebox() {
|
||||
# Message box
|
||||
#
|
||||
# Variables:
|
||||
# MSGBOX_TITLE -- title (centered and bold);
|
||||
# MSGBOX_WIDTH -- terminal width. Default: 75 cols;
|
||||
# MSGBOX_HELP -- help message.
|
||||
tput smcup # save screen contents
|
||||
tput civis # hide terminal cursor
|
||||
clear # clear screen
|
||||
|
||||
local w=""
|
||||
[ "$MSGBOX_WIDTH" ] && w="$MSGBOX_WIDTH" || w=75
|
||||
|
||||
if [ "$MSGBOX_TITLE" ]; then
|
||||
local hw=$(( ( ( $w - ${#MSGBOX_TITLE} ) - 2 ) / 2 ))
|
||||
local chars=0
|
||||
local filler=""
|
||||
while [ $chars -ne $hw ]; do filler+=" "; let chars++; done
|
||||
MSGBOX_TITLE=$(tr '[:lower:]' '[:upper:]' <<< ${MSGBOX_TITLE})
|
||||
echo -e "$filler \e[1m$MSGBOX_TITLE\e[0m $filler"
|
||||
fi
|
||||
|
||||
echo -e "$@" #| fmt --width="$w" # diplay message
|
||||
|
||||
if [ "$MSGBOX_HELP" ]; then
|
||||
echo -e "$MSGBOX_HELP"
|
||||
else
|
||||
tput cup $(tput lines) 0
|
||||
echo -en "\e[7mPress any key to quit\e[27m"
|
||||
tput home
|
||||
fi
|
||||
|
||||
read -r -s -n 1 inp
|
||||
case "$inp" in
|
||||
* ) clear -x; tput rmcup; tput cnorm; return 0;;
|
||||
esac
|
||||
}
|
||||
|
||||
yesno() {
|
||||
# Yes/No interactive dialog
|
||||
#
|
||||
# Variales:
|
||||
# ASSUME_YES -- skip dialog, return "Yes";
|
||||
# YN_INDENT -- indent;
|
||||
# YN_HELP -- help text.
|
||||
|
||||
[ "$ASSUME_YES" ] && return 0
|
||||
|
||||
tput smcup # save screen contents
|
||||
tput civis # hide terminal cursor
|
||||
|
||||
local pos=0
|
||||
local yn=( Yes No )
|
||||
local answer=
|
||||
local prompt="$@"
|
||||
|
||||
while [[ ! "$inp" =~ [qQ] ]]; do
|
||||
clear
|
||||
|
||||
if [ "$prompt" ]
|
||||
then echo -e "$prompt"
|
||||
else echo -e "Continue?\n"
|
||||
fi
|
||||
|
||||
for i in "${!yn[@]}"; do
|
||||
[ "$YN_INDENT" ] && echo -en "$YN_INDENT"
|
||||
|
||||
if [ $i -eq $pos ]
|
||||
then echo -en "> \e[7m${yn[${i}]}\e[27m\t"
|
||||
else echo -en " ${yn[${i}]}\t"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$YN_HELP" ]; then
|
||||
echo -en "$YN_HELP"
|
||||
else
|
||||
tput cup $(tput lines) 0
|
||||
echo -en "\e[7mY - yes, N - no, q to qiut\e[27m"
|
||||
tput home
|
||||
fi
|
||||
|
||||
# Read input (including arrow keys)
|
||||
local inp=
|
||||
local escape_char=$(printf "\u1b")
|
||||
read -r -s -n 1 inp # get 1 character
|
||||
# Read 2 more chars
|
||||
if [[ $inp == $escape_char ]]; then read -r -s -n 2 inp; fi
|
||||
|
||||
case "$inp" in
|
||||
[[hHjJ]|'[A'|'[D' ) pos=$(( $pos - 1 )) ;; # move up
|
||||
[]kKlL]|'[B'|'[C' ) pos=$(( $pos + 1 )) ;; # move down
|
||||
[yY] ) answer=Yes; break ;;
|
||||
[nN] ) answer=No; break ;;
|
||||
'' ) answer="${yn[${pos}]}"; break ;; # enter
|
||||
esac
|
||||
|
||||
# Jump to last item if user press "up" when pos=0 and vice versa
|
||||
if [ $pos -lt 0 ]; then pos=$(( ${#yn[@]} - 1 )); fi
|
||||
if [ $pos -gt $(( ${#yn[@]} - 1 )) ]; then pos=0; fi
|
||||
done
|
||||
|
||||
case $answer in
|
||||
Yes) answer=0;;
|
||||
No) answer=1;;
|
||||
esac
|
||||
|
||||
tput rmcup # restore screen
|
||||
tput cnorm # show cursor
|
||||
|
||||
return $answer # return exit code
|
||||
}
|
Reference in New Issue
Block a user