@@ -244,6 +244,56 @@ function execute_command_checked()
244244}
245245
246246
247+ # Custom `select` implementation that allows *empty* input.
248+ # Pass the choices as individual arguments.
249+ # Output is the chosen item, or "", if the user just pressed ENTER.
250+ # Example:
251+ # choice=$(select_with_default 'one' 'two' 'three')
252+ # Attribution: This is copied with minor modifications from here:
253+ # https://stackoverflow.com/a/42790579/2059999
254+ #
255+ # If SELECTION_OVERRIDE is set then we use that value, otherwise we
256+ # query the user.
257+ #
258+ select_with_default () {
259+
260+ local item i=0 numItems=$#
261+
262+ if [ ! -z ${SELECTION_OVERRIDE} ]; then
263+ printf %s " ${SELECTION_OVERRIDE} "
264+ return
265+ fi
266+
267+ if [[ " ${numItems} " == " 1" ]]; then
268+ printf %s " ${1} "
269+ return
270+ fi
271+
272+ # Print numbered menu items, based on the arguments passed.
273+ for item; do # Short for: for item in " $@ " ; do
274+ printf ' %s\n' " $(( ++ i)) ) $item "
275+ done >&2 # Print to stderr, as `select` does.
276+
277+ # Prompt the user for the index of the desired item.
278+ while : ; do
279+ printf %s " ${PS3-# ? } " >&2 # Print the prompt string to stderr, as `select` does.
280+ read -r index
281+ # Make sure that the input is either empty or that a valid index was entered.
282+ [[ -z $index ]] && break # empty input
283+ (( index >= 1 && index <= numItems )) 2> /dev/null || { echo " Invalid selection. Please try again." >&2 ; continue ; }
284+ break
285+ done
286+
287+ if [ -z $index ]; then
288+ index=1
289+ fi
290+ # echo -e ">>> index '${index}'" >&2
291+ # echo -e ">>> opt1 '${1}'" >&2
292+ # echo -e ">>> opt2 '${1}'" >&2
293+
294+ # Output the selected item, if any.
295+ [[ -n $index ]] && printf %s " ${@: index: 1} "
296+ }
247297
248298
249299
0 commit comments