Skip to content

Commit a391713

Browse files
committed
Use PS0 and function substitution in Bash 5.3
1 parent e644783 commit a391713

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

bash-preexec.sh

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,15 @@ __bp_preexec_invoke_exec() {
291291
__bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command"
292292
}
293293

294+
__bp_invoke_preexec_from_ps0() {
295+
__bp_last_argument_prev_command="${1:-}"
296+
297+
local this_command
298+
__bp_load_this_command_from_history || return
299+
300+
__bp_invoke_preexec_functions "${__bp_last_ret_value:-}" "$__bp_last_argument_prev_command" "$this_command"
301+
}
302+
294303
# This function invokes every function defined in our function array
295304
# "preexec_function". This function receives the arguments $1 and $2 for $?
296305
# and $_, respectively, which will be set for each preexec function. The third
@@ -320,12 +329,7 @@ __bp_invoke_preexec_functions() {
320329
__bp_set_ret_value "$preexec_ret_value"
321330
}
322331

323-
__bp_install() {
324-
# Exit if we already have this installed.
325-
if [[ "${PROMPT_COMMAND[*]:-}" == *"__bp_precmd_invoke_cmd"* ]]; then
326-
return 1
327-
fi
328-
332+
__bp_hook_preexec_into_debug() {
329333
local trap_string
330334
trap_string=$(trap -p DEBUG)
331335
trap '__bp_preexec_invoke_exec "$_"' DEBUG
@@ -355,6 +359,27 @@ __bp_install() {
355359
set -o functrace > /dev/null 2>&1
356360
shopt -s extdebug > /dev/null 2>&1
357361
fi
362+
}
363+
364+
__bp_hook_preexec_into_ps0() {
365+
# shellcheck disable=SC2016
366+
PS0=${PS0-}'${ __bp_invoke_preexec_from_ps0 "$_"; }'
367+
368+
# Adjust our HISTCONTROL Variable if needed.
369+
__bp_adjust_histcontrol
370+
}
371+
372+
__bp_install() {
373+
# Exit if we already have this installed.
374+
if [[ "${PROMPT_COMMAND[*]:-}" == *"__bp_precmd_invoke_cmd"* ]]; then
375+
return 1
376+
fi
377+
378+
if (( BASH_VERSINFO[0] > 5 || (BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 3) )); then
379+
__bp_hook_preexec_into_ps0
380+
else
381+
__bp_hook_preexec_into_debug
382+
fi
358383

359384
local existing_prompt_command
360385
# Remove setting our trap install string and sanitize the existing prompt command string
@@ -392,7 +417,7 @@ __bp_install() {
392417
# Note: We need to add "trace" attribute to the function so that "trap
393418
# ... DEBUG" inside "__bp_install" takes an effect even when there was an
394419
# existing DEBUG trap.
395-
declare -ft __bp_install
420+
declare -ft __bp_install __bp_hook_preexec_into_debug
396421

397422
# Sets an installation string as part of our PROMPT_COMMAND to install
398423
# after our session has started. This allows bash-preexec to be included

test/bash-preexec.bats

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,11 @@ set_exit_code_and_run_precmd() {
9494
bp_install
9595
trap_count_snapshot=$trap_invoked_count
9696

97-
[ "$(trap -p DEBUG | cut -d' ' -f3)" == "'__bp_preexec_invoke_exec" ]
98-
[[ "${preexec_functions[*]}" == *"__bp_original_debug_trap"* ]] || return 1
97+
if (( BASH_VERSINFO[0] < 5 || (BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] < 3) )); then
98+
# We override the DEBUG trap in Bash < 5.3
99+
[ "$(trap -p DEBUG | cut -d' ' -f3)" == "'__bp_preexec_invoke_exec" ]
100+
[[ "${preexec_functions[*]}" == *"__bp_original_debug_trap"* ]] || return 1
101+
fi
99102

100103
__bp_interactive_mode # triggers the DEBUG trap
101104

0 commit comments

Comments
 (0)