fix: multiselect nameref collision with options/defaults arrays

This commit is contained in:
pyr0ball 2026-07-18 22:31:30 -07:00
parent 7b63dbca46
commit 6090507530

View file

@ -1068,12 +1068,17 @@ multiselect(){
get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
local return_value=$1 local return_value=$1
local -n options=$2 # Nameref-aliased to the caller's arrays. Named _ms_* (not "options"/
local -n defaults=$3 # "defaults") because a nameref that happens to share its target
# variable's exact name triggers a "circular name reference" from bash
# and silently unreliable behavior - a caller passing arrays literally
# named $options/$defaults would otherwise break this.
local -n _ms_options=$2
local -n _ms_defaults=$3
local selected=() local selected=()
for ((i=0; i<${#options[@]}; i++)); do for ((i=0; i<${#_ms_options[@]}; i++)); do
if [[ ${defaults[i]} = "true" ]]; then if [[ ${_ms_defaults[i]} = "true" ]]; then
selected+=("true") selected+=("true")
else else
selected+=("false") selected+=("false")
@ -1083,7 +1088,7 @@ multiselect(){
# determine current screen position for overwriting the options # determine current screen position for overwriting the options
local lastrow=`get_cursor_row` local lastrow=`get_cursor_row`
local startrow=$(($lastrow - ${#options[@]})) local startrow=$(($lastrow - ${#_ms_options[@]}))
# ensure cursor and input echoing back on upon a ctrl+c during read -s # ensure cursor and input echoing back on upon a ctrl+c during read -s
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2 trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
@ -1115,7 +1120,7 @@ multiselect(){
print_options() { print_options() {
# print options by overwriting the last lines # print options by overwriting the last lines
local idx=0 local idx=0
for option in "${options[@]}"; do for option in "${_ms_options[@]}"; do
#local prefix="[ ]" #local prefix="[ ]"
local prefix="${gry}${deselected_opt}${dfl}" local prefix="${gry}${deselected_opt}${dfl}"
if [[ ${selected[idx]} == true ]]; then if [[ ${selected[idx]} == true ]]; then
@ -1142,9 +1147,9 @@ multiselect(){
space) toggle_option $active;; space) toggle_option $active;;
enter) print_options -1; break;; enter) print_options -1; break;;
up) ((active--)); up) ((active--));
if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi;; if [ $active -lt 0 ]; then active=$((${#_ms_options[@]} - 1)); fi;;
down) ((active++)); down) ((active++));
if [ $active -ge ${#options[@]} ]; then active=0; fi;; if [ $active -ge ${#_ms_options[@]} ]; then active=0; fi;;
esac esac
done done