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
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
|
|
|