Skip to content

Commit

Permalink
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dorothy-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
setup-util-dash
setup-util-ksh
setup-util-carapace
dorothy install
dorothy --slug=${{ github.repository }} install
# nu -c 'echo $nu.loginshell-path'
- name: 'Dorothy Login Shell: bash'
shell: bash -leo pipefail {0}
Expand Down
102 changes: 62 additions & 40 deletions commands/choose
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/usr/bin/env bash

# @todo tests for solo item, tests for fuzzy and exact defaults
# @todo see if the [ nothing selected ] is blockquote in ask, and if so, make it blockquote here too

function choose_test() (
source "$DOROTHY/sources/bash.bash"
echo-style --h1="TEST: $0"
Expand Down Expand Up @@ -501,14 +504,17 @@ function choose_() (
--defaults-fuzzy=<newline separated values>
Pre-select <value>s by fuzzy matching.
--[no-]confirm=[yes|no]
Confirm the (default/entered) value(s) before continuing.
--[no-]skip-solo=[YES|no] | --[no-]confirm-solo=[NO|yes]
If a selection is required, and there is only a single item, the solo item will be selected. This option skips the prompt for the required solo item, sending it without doing the prompt. Defaults to disabled.
--[no-]confirm-default=[YES|no] | --[no-]skip-default=[yes|NO]
Confirm the default value(s) (if provided) before continuing. Defaults to enabled.
--[no-]skip-default=[yes|NO] | --[no-]confirm-default=[YES|no]
If there are defaults, skip the prompt and send the defaults. Defaults to disabled.
--[no-]confirm-input=[yes|NO]
Confirm the entered value(s) before continuing. Defaults to disabled.
Have the choose menu confirm the user's input (their selection or lack of selection). Defaults to disabled.
--[no-]confirm=[yes|no]
HAve the prompt not skip any step, requiring solo values to be prompted, default values to be prompted, and selections or their lack of to be confirmed.
--[no-]required=[yes|NO]
Do not continue until a selection is made. Disable aborting the prompt.
Expand Down Expand Up @@ -539,7 +545,7 @@ function choose_() (
local option_question=()
# trunk-ignore(shellcheck/SC2016)
local option_label='no' option_visual='' option_return='$VALUE'
local defaults_exact=() defaults_fuzzy=() option_confirm_default='yes' option_confirm_input='no'
local defaults_exact=() defaults_fuzzy=() option_confirm_solo='yes' option_confirm_default='yes' option_confirm_input='no'
local option_required='no' option_multi='no'
local option_linger='no' option_timeout=''
while test "$#" -ne 0; do
Expand All @@ -566,6 +572,12 @@ function choose_() (
mapfile -t tmp <<<"${item#*=}"
defaults_fuzzy+=("${tmp[@]}")
;;
'--no-skip-solo'* | '--skip-solo'*)
option_confirm_solo="$(get-flag-value --non-affirmative --fallback="$option_confirm_solo" -- "$item")"
;;
'--no-confirm-solo'* | '--confirm-solo'*)
option_confirm_solo="$(get-flag-value --affirmative --fallback="$option_confirm_solo" -- "$item")"
;;
'--no-skip-default'* | '--skip-default'*)
option_confirm_default="$(get-flag-value --non-affirmative --fallback="$option_confirm_default" -- "$item")"
;;
Expand All @@ -576,6 +588,7 @@ function choose_() (
option_confirm_input="$(get-flag-value --affirmative --fallback="$option_confirm_input" -- "$item")"
;;
'--no-confirm'* | '--confirm'*)
option_confirm_solo="$(get-flag-value --affirmative --fallback="$option_confirm_solo" -- "$item")"
option_confirm_default="$(get-flag-value --affirmative --fallback="$option_confirm_default" -- "$item")"
option_confirm_input="$(get-flag-value --affirmative --fallback="$option_confirm_input" -- "$item")"
;;
Expand Down Expand Up @@ -667,9 +680,9 @@ function choose_() (
fi

# generic helpers
function __fuzzy_haystack_needle {
local haystack="$1" needle="$2"
[[ "$(__lowercase_string "$haystack")" == *"$(__lowercase_string "$needle")"* ]]
function __string_has_case_insensitive_substring {
local string="$1" substring="$2"
[[ "$(__lowercase_string "$string")" == *"$(__lowercase_string "$substring")"* ]]
return
}

Expand All @@ -693,7 +706,7 @@ function choose_() (

# generate the items
# @todo add support for option_defaults_indexes if a user requests it
local index item INDEX=-1 VALUE LABEL VISUAL RETURN items=() returns=() defaults=() defaults_indexes=() defaults_count=0 defaults_last=-1 fallbacks_indexes=() fallbacks_count=0 fallbacks_last=-1
local index item INDEX=-1 VALUE LABEL VISUAL RETURN items=() returns=() defaults=() items_count can_skip_prompt='no' defaults_indexes=() defaults_count=0 defaults_last=-1 fallbacks_indexes=() fallbacks_count=0 fallbacks_last=-1
for ((index = 0; index < ${#inputs[@]}; index = index + inputs_step)); do
# index considers inputs_step, INDEX is only each item (label/value combo)
INDEX=$((INDEX + 1))
Expand Down Expand Up @@ -730,9 +743,10 @@ function choose_() (
defaults[INDEX]='yes'
fi
done
elif test "${#defaults_fuzzy[@]}" -ne 0; then # bash v3 compat
fi
if test "${#defaults_fuzzy[@]}" -ne 0; then # bash v3 compat
for item in "${defaults_fuzzy[@]}"; do
if __fuzzy_haystack_needle "$VALUE" "$item"; then
if __string_has_case_insensitive_substring "$VALUE" "$item"; then
defaults[INDEX]='yes'
fi
done
Expand Down Expand Up @@ -760,6 +774,13 @@ function choose_() (
items+=("$VISUAL")
returns+=("$RETURN")
done
items_count="${#items[@]}"
if test "$items_count" -eq 1 -a "$option_required" = 'yes'; then
defaults[0]='yes'
if test "$option_confirm_solo" = 'no'; then
can_skip_prompt='yes'
fi
fi
defaults_count="${#defaults[@]}"
defaults_indexes=("${!defaults[@]}")

Expand All @@ -769,6 +790,9 @@ function choose_() (
defaults_last="$((defaults_count - 1))"
can_revert_to_defaults='yes'
can_cancel='yes'
if test "$option_confirm_default" = 'no'; then
can_skip_prompt='yes'
fi
else
can_revert_to_defaults='no'
if test "$option_required" = 'no'; then
Expand All @@ -794,7 +818,6 @@ function choose_() (
local \
commentary='' \
content_columns \
items_count="${#items[@]}" \
items_last \
items_renders \
items_rows \
Expand Down Expand Up @@ -837,7 +860,11 @@ function choose_() (
text__pick_nothing_cancel='cancel with nothing'
text__pick_nothing_choose='choose from nothing'
text__pick_nothing_confirm='confirm with nothing'
if test "$option_multi" = 'yes'; then
if test "$items_count" -eq 1 -a "$option_required" = 'yes'; then
text__pick_cancel='cancel to the'
text__pick_choose='choose the'
text__pick_confirm='confirm the'
elif test "$option_multi" = 'yes'; then
text__pick_cancel='cancel to the'
text__pick_choose='choose any of'
text__pick_confirm='confirm the'
Expand Down Expand Up @@ -1316,22 +1343,17 @@ function choose_() (
}
function set_menu_mode {
local new="$1"
# sanity check if confirm is appropriate
# sanity check if new menu is appropriate
if test "$option_required" = 'yes'; then
if test "$new" = 'confirm'; then
if test "$selected_count" -eq 0; then
menu_skip_render='yes'
menu_mode='choose'
__print_string "$style__bell" >"$tty_target"
return 0
fi
elif test "$new" = 'cancel'; then
if test "$fallbacks_count" -eq 0; then
menu_skip_render='yes'
menu_mode='choose'
__print_string "$style__bell" >"$tty_target"
return 0
fi
# if required, and trying to do proceed without items, then go back to choose and send a bell
if
test "$selected_count" -eq 0 && test "$new" = 'confirm' -o "$new" = 'confirmed' ||
test "$fallbacks_count" -eq 0 -a "$new" = 'cancel'
then
menu_skip_render='yes'
menu_mode='choose'
__print_string "$style__bell" >"$tty_target"
return 0
fi
fi
# check if we need to recalculate paging and update the mode
Expand Down Expand Up @@ -1846,24 +1868,24 @@ function choose_() (
if test "$selected_count" -ne 0; then
commentary="${style__input_warning}[timed out: using defaults]${style__end__input_warning}"
action_revert
set_menu_mode 'finished'
set_menu_mode 'exit'
break
elif test "$option_required" = 'no'; then
commentary="${style__input_warning}[timed out: not required]${style__end__input_warning}"
action_none
set_menu_mode 'finished'
set_menu_mode 'exit'
break
else
commentary="${style__input_error}[input failure: timed out: required]${style__end__input_error}"
menu_status="$read_status" # error cases no seleciotn
set_menu_mode 'finished'
set_menu_mode 'exit'
break
fi
elif test "$read_status" -ne 0; then
# some other failure
commentary="${style__input_error}[input failure: $read_status]${style__end__input_error}"
menu_status="$read_status" # error causes no selection
set_menu_mode 'finished'
set_menu_mode 'exit'
break
elif test "$terminal_too_short" = 'yes'; then
continue
Expand Down Expand Up @@ -1908,15 +1930,15 @@ function choose_() (
# CANCEL MENU
if test "$key" = 'enter' -o "$key" = 'e' || test "$key" = 'space' -a "$option_multi" = 'no'; then
action_revert
set_menu_mode 'finished'
set_menu_mode 'confirmed'
break
elif test "$key" = 'escape' -o "$key" = 'q'; then
set_menu_mode 'choose'
fi
elif test "$menu_mode" = 'confirm'; then
# CONFIRM MENU
if test "$key" = 'enter' -o "$key" = 'e' || test "$key" = 'space' -a "$option_multi" = 'no'; then
set_menu_mode 'finished'
set_menu_mode 'confirmed'
break
elif test "$key" = 'escape' -o "$key" = 'q'; then
set_menu_mode 'choose'
Expand All @@ -1929,7 +1951,7 @@ function choose_() (
if test "$option_confirm_input" = 'yes'; then
set_menu_mode 'confirm'
else
set_menu_mode 'finished'
set_menu_mode 'confirmed'
break
fi
fi
Expand All @@ -1938,7 +1960,7 @@ function choose_() (
set_menu_mode 'cancel'
else
action_revert
set_menu_mode 'finished'
set_menu_mode 'confirmed'
break
fi
elif test "$key" = 'enter' -o "$key" = 'e'; then
Expand All @@ -1948,7 +1970,7 @@ function choose_() (
if test "$option_confirm_input" = 'yes'; then
set_menu_mode 'confirm'
else
set_menu_mode 'finished'
set_menu_mode 'confirmed'
break
fi
elif test "$key" = 'z'; then
Expand Down Expand Up @@ -1987,7 +2009,7 @@ function choose_() (
fi

# finish if finished
if test "$menu_mode" = 'finished'; then
if test "$menu_mode" = 'confirmed' -o "$menu_mode" = 'exit'; then
break
fi
done
Expand All @@ -1999,7 +2021,7 @@ function choose_() (
select_defaults

# render if not skipping
if test "$option_confirm_default" = 'no' -a "$can_revert_to_defaults" = 'yes'; then
if test "$can_skip_prompt" = 'yes'; then
: # we have defaults, and want to skip defaults
else
handle_menu
Expand Down
14 changes: 9 additions & 5 deletions commands/dorothy
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ function dorothy_() (
Show this help information.
--slug=<slug>
If Dorothy needs to be installed/updated, checkout this slug.
If Dorothy needs to be installed/updated, use this slug.
--branch=<branch>
If Dorothy needs to be installed/updated, checkout this branch.
If Dorothy needs to be fresh installed, checkout this branch.
--reference=<reference> | --commit=<reference>
If Dorothy needs to be installed/updated, checkout this reference.
If Dorothy needs to be fresh installed, checkout this reference.
--remote-name=<remote>
If Dorothy needs to be installed/updated, use this remote name.
Expand Down Expand Up @@ -851,6 +851,8 @@ function dorothy_() (
function __update_modern_dorothy {
if __command_exists -- echo-style git-helper; then
echo-style --h2="Updating the Dorothy installation at $DOROTHY from $the_browse_url" || return
# verify it is a repository
git-helper verify
# update origin first
git-helper update --path="$DOROTHY" || return
# update upstream second
Expand Down Expand Up @@ -1104,10 +1106,12 @@ function dorothy_() (
}
function update_user {
echo-style --h2="Updating the Dorothy user configuration at $DOROTHY/user"
if ! git-helper update --path="$DOROTHY/user"; then
if ! git-helper --verify update --path="$DOROTHY/user"; then
__print_lines '...Dorothy user configuration was unable to be updated, you will have to figure this out later...'
echo-style --n2="Updating the Dorothy user configuration at $DOROTHY/user"
else
echo-style --g2="Updating the Dorothy user configuration at $DOROTHY/user"
fi
echo-style --g2="Updating the Dorothy user configuration at $DOROTHY/user"
}

# update or install the user configuration based on its presence
Expand Down
Loading

0 comments on commit f0ab67f

Please sign in to comment.