Skip to content

Commit 139e074

Browse files
committed
Use PS0 and function substitution in Bash 5.3
1 parent 3bad103 commit 139e074

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
@@ -289,6 +289,15 @@ __bp_preexec_invoke_exec() {
289289
__bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command"
290290
}
291291

292+
__bp_invoke_preexec_from_ps0() {
293+
__bp_last_argument_prev_command="${1:-}"
294+
295+
local this_command
296+
__bp_load_this_command_from_history || return
297+
298+
__bp_invoke_preexec_functions "${__bp_last_ret_value:-}" "$__bp_last_argument_prev_command" "$this_command"
299+
}
300+
292301
# This function invokes every function defined in our function array
293302
# "preexec_function". This function receives the arguments $1 and $2 for $?
294303
# and $_, respectively, which will be set for each preexec function. The third
@@ -318,12 +327,7 @@ __bp_invoke_preexec_functions() {
318327
__bp_set_ret_value "$preexec_ret_value"
319328
}
320329

321-
__bp_install() {
322-
# Exit if we already have this installed.
323-
if [[ "${PROMPT_COMMAND[*]:-}" == *"__bp_precmd_invoke_cmd"* ]]; then
324-
return 1
325-
fi
326-
330+
__bp_hook_preexec_into_debug() {
327331
local trap_string
328332
trap_string=$(trap -p DEBUG)
329333
trap '__bp_preexec_invoke_exec "$_"' DEBUG
@@ -351,6 +355,27 @@ __bp_install() {
351355
set -o functrace > /dev/null 2>&1
352356
shopt -s extdebug > /dev/null 2>&1
353357
fi
358+
}
359+
360+
__bp_hook_preexec_into_ps0() {
361+
# shellcheck disable=SC2016
362+
PS0=${PS0-}'${ __bp_invoke_preexec_from_ps0 "$_"; }'
363+
364+
# Adjust our HISTCONTROL Variable if needed.
365+
__bp_adjust_histcontrol
366+
}
367+
368+
__bp_install() {
369+
# Exit if we already have this installed.
370+
if [[ "${PROMPT_COMMAND[*]:-}" == *"__bp_precmd_invoke_cmd"* ]]; then
371+
return 1
372+
fi
373+
374+
if (( BASH_VERSINFO[0] > 5 || (BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 3) )); then
375+
__bp_hook_preexec_into_ps0
376+
else
377+
__bp_hook_preexec_into_debug
378+
fi
354379

355380
local existing_prompt_command
356381
# Remove setting our trap install string and sanitize the existing prompt command string
@@ -388,7 +413,7 @@ __bp_install() {
388413
# Note: We need to add "trace" attribute to the function so that "trap
389414
# ... DEBUG" inside "__bp_install" takes an effect even when there was an
390415
# existing DEBUG trap.
391-
declare -ft __bp_install
416+
declare -ft __bp_install __bp_hook_preexec_into_debug
392417

393418
# Sets an installation string as part of our PROMPT_COMMAND to install
394419
# 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)