From 6b08284928b0db4cc8dcfc6f58f34484e2f1ef6d Mon Sep 17 00:00:00 2001 From: John D Pell Date: Fri, 28 Jan 2022 12:13:43 -0800 Subject: [PATCH 1/4] Update "preexec" from "https://github.com/rcaloras/bash-preexec@master" git-vendor-name: preexec git-vendor-dir: vendor/github.com/rcaloras/bash-preexec git-vendor-repository: https://github.com/rcaloras/bash-preexec git-vendor-ref: fd2ffa8876d3940c97ffdc3cc807e43277cf72da --- lib/preexec.bash | 8 ++--- .../rcaloras/bash-preexec/bash-preexec.sh | 32 ++++++++++++------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/preexec.bash b/lib/preexec.bash index 17cabdf974..db54a60006 100644 --- a/lib/preexec.bash +++ b/lib/preexec.bash @@ -4,9 +4,8 @@ # Load the `bash-preexec.sh` library, and define helper functions ## Prepare, load, fix, and install `bash-preexec.sh` -: "${PROMPT_COMMAND:=}" -# Disable immediate `$PROMPT_COMMAND` modification +# Disable `$PROMPT_COMMAND` modification for now. __bp_delay_install="delayed" # shellcheck source-path=SCRIPTDIR/../vendor/github.com/rcaloras/bash-preexec @@ -20,7 +19,6 @@ function __bp_require_not_readonly() { :; } # Disable trap DEBUG on subshells - https://github.com/Bash-it/bash-it/pull/1040 __bp_enable_subshells= # blank -set +T # Modify `$PROMPT_COMMAND` now __bp_install_after_session_init @@ -42,7 +40,7 @@ function safe_append_prompt_command { local prompt_re f __bp_trim_whitespace f "${1?}" - if [ "${__bp_imported:-missing}" == "defined" ]; then + if [ "${bash_preexec_imported:-${__bp_imported:-missing}}" == "defined" ]; then # We are using bash-preexec if ! __check_precmd_conflict "${f}"; then precmd_functions+=("${f}") @@ -71,7 +69,7 @@ function safe_append_preexec { local prompt_re f __bp_trim_whitespace f "${1?}" - if [ "${__bp_imported:-missing}" == "defined" ]; then + if [ "${bash_preexec_imported:-${__bp_imported:-missing}}" == "defined" ]; then # We are using bash-preexec if ! __check_preexec_conflict "${f}"; then preexec_functions+=("${f}") diff --git a/vendor/github.com/rcaloras/bash-preexec/bash-preexec.sh b/vendor/github.com/rcaloras/bash-preexec/bash-preexec.sh index c23d0381cc..5f1208c33e 100644 --- a/vendor/github.com/rcaloras/bash-preexec/bash-preexec.sh +++ b/vendor/github.com/rcaloras/bash-preexec/bash-preexec.sh @@ -32,11 +32,20 @@ # using: the "DEBUG" trap, and the "PROMPT_COMMAND" variable. If you override # either of these after bash-preexec has been installed it will most likely break. +# Make sure this is bash that's running and return otherwise. +if [[ -z "${BASH_VERSION:-}" ]]; then + return 1; +fi + # Avoid duplicate inclusion -if [[ "${__bp_imported:-}" == "defined" ]]; then +if [[ -n "${bash_preexec_imported:-}" ]]; then return 0 fi -__bp_imported="defined" +bash_preexec_imported="defined" + +# WARNING: This variable is no longer used and should not be relied upon. +# Use ${bash_preexec_imported} instead. +__bp_imported="${bash_preexec_imported}" # Should be available to each precmd and preexec # functions, should they want it. $? and $_ are available as $? and $_, but @@ -70,7 +79,8 @@ __bp_require_not_readonly() { # history even if it starts with a space. __bp_adjust_histcontrol() { local histcontrol - histcontrol="${HISTCONTROL//ignorespace}" + histcontrol="${HISTCONTROL:-}" + histcontrol="${histcontrol//ignorespace}" # Replace ignoreboth with ignoredups if [[ "$histcontrol" == *"ignoreboth"* ]]; then histcontrol="ignoredups:${histcontrol//ignoreboth}" @@ -85,6 +95,10 @@ __bp_adjust_histcontrol() { # and unset as soon as the trace hook is run. __bp_preexec_interactive_mode="" +# These arrays are used to add functions to be run before, or after, prompts. +declare -a precmd_functions +declare -a preexec_functions + # Trims leading and trailing whitespace from $2 and writes it to the variable # name passed as $1 __bp_trim_whitespace() { @@ -154,7 +168,7 @@ __bp_set_ret_value() { __bp_in_prompt_command() { local prompt_command_array - IFS=$'\n;' read -rd '' -a prompt_command_array <<< "$PROMPT_COMMAND" + IFS=$'\n;' read -rd '' -a prompt_command_array <<< "${PROMPT_COMMAND:-}" local trimmed_arg __bp_trim_whitespace trimmed_arg "${1:-}" @@ -292,7 +306,8 @@ __bp_install() { local existing_prompt_command # Remove setting our trap install string and sanitize the existing prompt command string - existing_prompt_command="${PROMPT_COMMAND//$__bp_install_string[;$'\n']}" # Edge case of appending to PROMPT_COMMAND + existing_prompt_command="${PROMPT_COMMAND:-}" + existing_prompt_command="${existing_prompt_command//$__bp_install_string[;$'\n']}" # Edge case of appending to PROMPT_COMMAND existing_prompt_command="${existing_prompt_command//$__bp_install_string}" __bp_sanitize_string existing_prompt_command "$existing_prompt_command" @@ -318,17 +333,12 @@ __bp_install() { # after our session has started. This allows bash-preexec to be included # at any point in our bash profile. __bp_install_after_session_init() { - # Make sure this is bash that's running this and return otherwise. - if [[ -z "${BASH_VERSION:-}" ]]; then - return 1; - fi - # bash-preexec needs to modify these variables in order to work correctly # if it can't, just stop the installation __bp_require_not_readonly PROMPT_COMMAND HISTCONTROL HISTTIMEFORMAT || return local sanitized_prompt_command - __bp_sanitize_string sanitized_prompt_command "$PROMPT_COMMAND" + __bp_sanitize_string sanitized_prompt_command "${PROMPT_COMMAND:-}" if [[ -n "$sanitized_prompt_command" ]]; then PROMPT_COMMAND=${sanitized_prompt_command}$'\n' fi; From a93919625ddb0f46d835ac6e0b272e1ee68d65aa Mon Sep 17 00:00:00 2001 From: John D Pell Date: Fri, 28 Jan 2022 11:52:59 -0800 Subject: [PATCH 2/4] lib/preexec: adobt `_bash_it_library_finalize_hook` Schedule modification of `$PROMPT_COMMAND` for after everything has loaded. --- lib/preexec.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/preexec.bash b/lib/preexec.bash index db54a60006..d1367d0b7a 100644 --- a/lib/preexec.bash +++ b/lib/preexec.bash @@ -20,8 +20,8 @@ function __bp_require_not_readonly() { :; } # Disable trap DEBUG on subshells - https://github.com/Bash-it/bash-it/pull/1040 __bp_enable_subshells= # blank -# Modify `$PROMPT_COMMAND` now -__bp_install_after_session_init +# Modify `$PROMPT_COMMAND` in finalize hook +_bash_it_library_finalize_hook+=('__bp_install_after_session_init') ## Helper functions function __check_precmd_conflict() { From c1943192ce6efbab7b4d3f843319dc5fce52d5aa Mon Sep 17 00:00:00 2001 From: John D Pell Date: Sun, 30 Jan 2022 11:37:18 -0800 Subject: [PATCH 3/4] lib/preexec: clarify subshell guard and comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite comment on disabling the `DEBUG` trap in subshells, which is now handled upstream as of rcaloras/bash-preexec#26. Alsö, fix the guard variable assignment to allow it to be overridden elsewhere (e.g., for testing). --- lib/preexec.bash | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/preexec.bash b/lib/preexec.bash index d1367d0b7a..8eba0e24fe 100644 --- a/lib/preexec.bash +++ b/lib/preexec.bash @@ -17,8 +17,9 @@ function __bp_adjust_histcontrol() { :; } # Don't fail on readonly variables function __bp_require_not_readonly() { :; } -# Disable trap DEBUG on subshells - https://github.com/Bash-it/bash-it/pull/1040 -__bp_enable_subshells= # blank +# For performance, testing, and to avoid unexpected behavior: disable DEBUG traps in subshells. +# See bash-it/bash-it#1040 and rcaloras/bash-preexec#26 +: "${__bp_enable_subshells:=}" # blank # Modify `$PROMPT_COMMAND` in finalize hook _bash_it_library_finalize_hook+=('__bp_install_after_session_init') From 8246794a28296b2a83de329c8a434fa0f010e359 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Fri, 11 Feb 2022 22:42:24 -0800 Subject: [PATCH 4/4] lib/preexec: the last remnants of the `$OSTYPE` have been swept away - Use a POSIX-compliant/portable extended regular expression to match on word-boundaries, rather than guessing which regex library `bash` was linked against. See https://stackoverflow.com/a/12696899/555333 for explanation and code suggestion. --- lib/preexec.bash | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/lib/preexec.bash b/lib/preexec.bash index 8eba0e24fe..1dbe8899fc 100644 --- a/lib/preexec.bash +++ b/lib/preexec.bash @@ -37,26 +37,20 @@ function __check_preexec_conflict() { _bash-it-array-contains-element "${f}" "${preexec_functions[@]}" } -function safe_append_prompt_command { - local prompt_re f - __bp_trim_whitespace f "${1?}" +function safe_append_prompt_command() { + local prompt_re prompt_er f - if [ "${bash_preexec_imported:-${__bp_imported:-missing}}" == "defined" ]; then + if [[ "${bash_preexec_imported:-${__bp_imported:-missing}}" == "defined" ]]; then # We are using bash-preexec + __bp_trim_whitespace f "${1?}" if ! __check_precmd_conflict "${f}"; then precmd_functions+=("${f}") fi else - # Set OS dependent exact match regular expression - if [[ ${OSTYPE} == darwin* ]]; then - # macOS - prompt_re="[[:<:]]${1}[[:>:]]" - else - # Linux, FreeBSD, etc. - prompt_re="\<${1}\>" - fi - - if [[ ${PROMPT_COMMAND} =~ ${prompt_re} ]]; then + # Match on word-boundaries + prompt_re='(^|[^[:alnum:]_])' + prompt_er='([^[:alnum:]_]|$)' + if [[ ${PROMPT_COMMAND} =~ ${prompt_re}"${1}"${prompt_er} ]]; then return elif [[ -z ${PROMPT_COMMAND} ]]; then PROMPT_COMMAND="${1}" @@ -66,12 +60,12 @@ function safe_append_prompt_command { fi } -function safe_append_preexec { +function safe_append_preexec() { local prompt_re f - __bp_trim_whitespace f "${1?}" - if [ "${bash_preexec_imported:-${__bp_imported:-missing}}" == "defined" ]; then + if [[ "${bash_preexec_imported:-${__bp_imported:-missing}}" == "defined" ]]; then # We are using bash-preexec + __bp_trim_whitespace f "${1?}" if ! __check_preexec_conflict "${f}"; then preexec_functions+=("${f}") fi