diff --git a/commands/ask b/commands/ask index 6821d6f71..78bdc2072 100755 --- a/commands/ask +++ b/commands/ask @@ -206,7 +206,7 @@ function ask_() ( load_dorothy_config 'styles.bash' # refresh the styles - refresh_style_cache -- 'question_title_prompt' 'question_title_result' 'question_body' 'input_warning' 'input_error' 'icon_prompt' 'result_value' 'icon_nothing_provided' 'icon_using_password' + refresh_style_cache -- 'question_title_prompt' 'question_title_result' 'question_body' 'input_warning' 'input_error' 'icon_prompt' 'result_value' 'icon_nothing_provided' 'icon_using_password' 'blockquote' # style the question local question_title_prompt='' question_title_result='' question_body_prompt='' @@ -230,8 +230,13 @@ function ask_() ( fi # adjust tty - local tty_target + local tty_target programmatic_stdin tty_target="$(is-tty --fallback)" + if test ! -t 0; then + programmatic_stdin='yes' + else + programmatic_stdin='no' + fi # helpers local ASKED='no' commentary='' @@ -248,60 +253,57 @@ function ask_() ( fi } function do_prompt { # has sideffects: RESULT, ASKED - local programmatic_stdin input_prompt __read_status __input_result result_prompt result_prompt_row_count clear='' p='' read_args=('-r') - if test ! -t 0; then - programmatic_stdin='yes' - else - programmatic_stdin='no' - input_prompt='' - if test -n "$question_title_prompt"; then - input_prompt+="$question_title_prompt"$'\n' - fi - if test -n "$question_body_prompt"; then - input_prompt+="$question_body_prompt"$'\n' - fi - input_prompt+="$style__icon_prompt" - fi + local input_prompt='' __read_status __input_result result_prompt result_prompt_row_count clear='' p='' read_args=('-r') if test -n "$option_timeout"; then read_args+=( -t "$option_timeout" ) fi + if test -n "$question_title_prompt"; then + input_prompt+="$question_title_prompt"$'\n' + fi + if test -n "$question_body_prompt"; then + input_prompt+="$question_body_prompt"$'\n' + fi + input_prompt+="$style__icon_prompt" + ASKED='yes' # not local while true; do # reset __read_status=0 __input_result='' + result_prompt="$input_prompt" + p="${clear}${result_prompt}" + clear='' # adapt according to read mode if test "$programmatic_stdin" = 'yes'; then # read in programmatic stdin mode behaves differently, so we have to account for that: # [-p ] is discarded, no prompt is shown # [-i ] is discarded, no default value is handled - # as such, do not pass such to read, do not manually bother with a prompt, and handle the default value ourself + # as such, do not pass such to read, do the prompt and handling of the default value ourself + __print_string "$p" >"$tty_target" # trunk-ignore(shellcheck/SC2162) IFS='' read "${read_args[@]}" __input_result || __read_status=$? - if test -z "$__input_result" -o "$__input_result" = $'\n'; then - # treat empty string and newline as default - : - elif [[ $__input_result =~ ^[\s]*$ ]]; then - # treat only whitespace as empty value - RESULT='' - else - # treat everything else as manual __input_result - RESULT="$__input_result" + if test "$__read_status" -eq 0; then + # the user has pressed enter, so trim it + result_prompt+="$RESULT"$'\n' + + if test -z "$__input_result" -o "$__input_result" = $'\n'; then + # treat empty string and newline as default + : + elif [[ $__input_result =~ ^[\s]*$ ]]; then + # treat only whitespace as empty value + RESULT='' + else + # treat everything else as manual __input_result + RESULT="$__input_result" + fi fi else - # we have tty stdin, can do a prompt - # -i requires -e - - # reset - result_prompt="$input_prompt" - p="${clear}${result_prompt}" - clear='' - # clear and prompt + # -i requires -e # trunk-ignore(shellcheck/SC2162) IFS= read "${read_args[@]}" -ei "$RESULT" -p "$p" __input_result || __read_status=$? @@ -313,13 +315,12 @@ function ask_() ( # the user has pressed enter, so note that an enter was rendered to the TTY so that it can be erased, and append a space so that it is not trimmed by "$(...)" usage result_prompt+="$RESULT"$'\n' fi # otherwise it has timed out. ctrl+c is not caught as we are not trapping it - - # generate our erasure - result_prompt="$(echo-wrap -- "$result_prompt")"$'\n' # "$()" trims the trailing newline, so add it back - result_prompt_row_count="$(echo-count-lines -- "$result_prompt")" - clear=$'\e['"$result_prompt_row_count"$'F\e[G\e[J' fi + # generate our erasure + result_prompt_row_count="$(echo-wrap -- "$result_prompt" | echo-count-lines --stdin)" + clear=$'\e['"$result_prompt_row_count"$'F\e[G\e[J' + # handle the result if test "$__read_status" -eq 142; then return 60 # ETIMEDOUT 60 Operation timed out @@ -338,7 +339,7 @@ function ask_() ( fi done # do the final erasure if necessary - if test "$programmatic_stdin" = 'no' -a -n "$clear"; then + if test -n "$clear"; then __print_string "$clear" >"$tty_target" fi # done @@ -442,13 +443,16 @@ function ask_() ( if test "$result_status" -eq 0; then # add the results only if lingering if test "$option_linger" = 'yes'; then + local content if test -z "$RESULT"; then - render+="${style__result_value}${style__icon_nothing_provided}${style__end__result_value}"$'\n' + content="$style__icon_nothing_provided" elif test "$option_password" = 'yes'; then - render+="${style__result_value}${style__icon_using_password}${style__end__result_value}"$'\n' + content="$style__icon_using_password" else - render+="${style__result_value}${RESULT}${style__end__result_value}"$'\n' + content="$RESULT" fi + content="${content//$'\n'/$'\n'"${style__blockquote}"}" # add the necessary indentation + render+="${style__result_value}${style__blockquote}${content}${style__end__result_value}"$'\n' # inform __print_string "$render" >"$tty_target" elif test -n "$commentary"; then diff --git a/commands/dorothy b/commands/dorothy index b825d4d1c..ddca08fb6 100755 --- a/commands/dorothy +++ b/commands/dorothy @@ -33,15 +33,19 @@ function dorothy_() ( set -e # vars that should be exported to subshells, which may or may not be inherited, as setup-environment-commands has not run yet - local self + local self="${BASH_SOURCE:-"$0"}" is_remote + if [[ $self == *'.local/share/dorothy/commands/dorothy' ]] && test -f "$self"; then + is_remote='no' + else + is_remote='yes' + fi export DOROTHY ZDOTDIR PATH XDG_CONFIG_HOME XDG_CACHE_HOME XDG_BIN_HOME XDG_DATA_HOME XDG_STATE_HOME if test -z "${DOROTHY-}"; then - # handle cron situation (dorothy is installed, however environment is empty) + # handle (1) fresh installation situation and (2) cron situation (dorothy is installed, however environment is empty) # `env -i "$(which dorothy)" run env` <-- whoami returns user who has dorothy installed: # `sudo env -i "$(which dorothy)" run env` <-- whoami returns root, who does not have dorothy installed - # @todo consider if this runs on zsh and bash v3 - self="${BASH_SOURCE:-"$0"}" - if [[ $self == *'.local/share/dorothy/commands/dorothy' ]] && test -f "$self"; then + if test "$is_remote" = 'no'; then + # handle fresh environment situation / cron situation DOROTHY="${self%/commands/dorothy*}" if test -z "${HOME-}"; then export HOME @@ -52,7 +56,7 @@ function dorothy_() ( USER="$(basename "$HOME")" fi else - # handle fresh install situation + # handle fresh installation situation DOROTHY='' fi fi @@ -298,7 +302,7 @@ function dorothy_() ( # Sourcing # the local installation exists, and the invoked [dorothy] command is of the local installation - if test -n "$DOROTHY" -a -f "$DOROTHY/sources/bash.bash" -a "$0" = "${BASH_SOURCE[0]}"; then + if test "$is_remote" = 'no' -a -n "$DOROTHY" -a -f "$DOROTHY/sources/bash.bash"; then # match with the local installation's [bash.bash] source "$DOROTHY/sources/bash.bash" else diff --git a/sources/bash.bash b/sources/bash.bash index 405076895..c00c0d114 100644 --- a/sources/bash.bash +++ b/sources/bash.bash @@ -123,7 +123,7 @@ function __command_missing { fi # proceed local command - for command in "${commands[@]}"; do + for command in "$@"; do if test "$command" = 'brew'; then # workaround for our [brew] wrapper if __is_brew; then @@ -151,7 +151,7 @@ function __command_exists { fi # proceed local command - for command in "${option_commands[@]}"; do + for command in "$@"; do if test "$command" = 'brew'; then # workaround for our [brew] wrapper if __is_brew; then