#!/usr/bin/env bash IFS="" function print_menu() # selected_item, ...menu_items { local function_arguments=($@) local selected_item="$1" local menu_items=(${function_arguments[@]:1}) local menu_size="${#menu_items[@]}" for (( i = 0; i < $menu_size; ++i )) do if [ "$i" = "$selected_item" ] then echo -e "\033[1;34m > \033[0m\e[1m${menu_items[i]}\033[0m" else echo " ${menu_items[i]}" fi done } function run_menu() # selected_item, ...menu_items { local function_arguments=($@) local selected_item="$1" local menu_items=(${function_arguments[@]:1}) local menu_size="${#menu_items[@]}" local menu_limit=$((menu_size - 1)) print_menu "$selected_item" "${menu_items[@]}" while read -rsn1 input do case "$input" in $'\x1B') # ESC ASCII code (https://dirask.com/posts/ASCII-Table-pJ3Y0j) read -rsn1 -t 0.1 input if [ "$input" = "[" ] # occurs before arrow code then read -rsn1 -t 0.1 input case "$input" in A) # Up Arrow if [ "$selected_item" -ge 1 ] then selected_item=$((selected_item - 1)) echo -en "\033[s\033[${menu_size}A" print_menu "$selected_item" "${menu_items[@]}" echo -en "\033[u\033[0m" fi ;; B) # Down Arrow if [ "$selected_item" -lt "$menu_limit" ] then selected_item=$((selected_item + 1)) echo -en "\033[s\033[${menu_size}A" print_menu "$selected_item" "${menu_items[@]}" echo -en "\033[u\033[0m" fi ;; esac fi read -rsn5 -t 0.1 # flushing stdin ;; "") # Enter key return "$selected_item" ;; esac done } # Usage example: selected_item=0 menu_items=("Stephan Stanisic " "Stephan Stanisic " "Stephan Stanisic " "Steph ") run_menu "$selected_item" "${menu_items[@]}" menu_result="$?" echo sel=${menu_items[$menu_result]} name=$(echo $sel | cut -d \< -f 1 | head -c -2) email=$(echo $sel | cut -d \< -f 2 | head -c -2) echo "Setting username to $name and email to $email" git config user.email "$email" git config user.name "$name"