mirror of
https://github.com/mjsarfatti/beddu.git
synced 2025-06-26 08:58:02 +02:00
81 lines
1.9 KiB
Bash
81 lines
1.9 KiB
Bash
#! /usr/bin/env bash
|
|
# choose.sh - Choose from a menu of options
|
|
|
|
# @depends on:
|
|
# - pen.sh
|
|
# - _symbols.sh
|
|
# - cursor.sh
|
|
|
|
# Print an interactive menu of options and return the selected option
|
|
#
|
|
# Usage:
|
|
# choose outvar text [choices...]
|
|
# Example:
|
|
# choose color "What is your favorite color?" "Red" "Blue" "Green"
|
|
# pen "You chose $color!"
|
|
choose() {
|
|
local -n outvar="$1"
|
|
local prompt
|
|
local options=("${@:3}") # Get options from third argument onwards
|
|
|
|
local current=0
|
|
local count=${#options[@]}
|
|
|
|
# Set prompt with default indicator
|
|
prompt=$(
|
|
pen -n blue "${_q:-?} "
|
|
pen -n "${2}"
|
|
pen gray "[↑↓]"
|
|
)
|
|
|
|
# Hide cursor for cleaner UI
|
|
hide_cursor
|
|
trap 'show_cursor; return' INT TERM
|
|
|
|
# Display initial prompt
|
|
pen "$prompt"
|
|
|
|
# Main loop
|
|
while true; do
|
|
local index=0
|
|
for item in "${options[@]}"; do
|
|
if ((index == current)); then
|
|
pen -n blue "${_O:-●} "
|
|
pen "${item}"
|
|
else
|
|
pen gray "${_o:-◌} ${item}"
|
|
fi
|
|
((index++))
|
|
done
|
|
|
|
# Read a single key press
|
|
read -s -r -n1 key
|
|
|
|
# Handle arrow/enter keys
|
|
if [[ $key == $'\e' ]]; then
|
|
read -s -r -n2 -t 0.0001 escape
|
|
key+="$escape"
|
|
fi
|
|
|
|
case "$key" in
|
|
$'\e[A' | 'k') # Up arrow or k
|
|
((current--))
|
|
[[ $current -lt 0 ]] && current=$((count - 1))
|
|
;;
|
|
$'\e[B' | 'j') # Down arrow or j
|
|
((current++))
|
|
[[ $current -ge "$count" ]] && current=0
|
|
;;
|
|
'') # Enter
|
|
break
|
|
;;
|
|
esac
|
|
|
|
# Clear screen and repeat
|
|
echo -en "\e[${count}A\e[J"
|
|
done
|
|
|
|
# Pass selected option back to caller
|
|
# shellcheck disable=SC2034
|
|
outvar="${options[$current]}"
|
|
}
|