#!/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