ao-mud is a spellbook of well-commented atomic bash scripts that each do one thing. we are building semantic building blocks for an autonomously-evolving digital spellcasting language.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
2.3 KiB

#!/usr/bin/env sh
# This script generates a menu from the given list of items. Choosing an item runs the command for that item.
# Usage: menu "Please choose" "item1 item2 item3" "ls cat command3"
# Use up/down arrow keys to select a menu item, then press Enter. Or cancel with ESC.
. colors
description=$1
items=($2)
commands=($3)
selected=0
displayed=0
# Calculate the position of the menu
menu_x=$((0))
menu_y=$(fathom-cursor -y)
# Calculate the number of rows that the menu will occupy
num_rows=${#items[@]}
# Calculate the maximum length of the item names
max_name_length=$(max-length "${items[*]}")
max_name_length=$((max_name_length))
# Define the function to display the menu
display_menu() {
# Get the dimensions of the terminal window (again each time in case window is resized)
window_width=$(fathom-terminal -w)
window_height=$(fathom-terminal -h)
# Recalculate the position of the menu
menu_y=$(fathom-cursor -y)
# Move the cursor to the correct position
if [ $displayed -eq 0 ]; then
# Don't move the cursor or clear the screen the first time
displayed=1
else
if [ $((menu_y + num_rows)) -ge $window_height ]; then
menu_y=$((window_height))
fi
move-cursor $menu_x $((menu_y - num_rows))
fi
# Print the items and commands
for i in "${!items[@]}"; do
if [ $i -eq $selected ]; then
printf "${CYAN}> %-${max_name_length}s${RESET} ${GREY}%s${RESET}\n" "${items[$i]}" "${commands[$i]}"
else
# Print the menu item plus extra spaces to cover up its command, since it's not selected
printf " %-${max_name_length}s %*s\n" "${items[$i]}" "${#commands[$i]}"
fi
done
}
# Define the function to handle key presses
handle_key() {
key=$(await-keypress)
case "$key" in
up)
selected=$((selected - 1))
if [ $selected -lt 0 ]; then
selected=$((num_rows - 1))
fi
;;
down)
selected=$((selected + 1))
if [ $selected -ge $num_rows ]; then
selected=0
fi
;;
enter)
cursor-blink on
command="${commands[$selected]}"
printf "\n"
eval $command
exit 0
;;
escape)
cursor-blink on
echo ESC
exit
;;
esac
}
cursor-blink off
# Display the menu's description
echo $description
# Menu loop
while true; do
display_menu
handle_key $key
done