|
| 1 | +# ble/contrib/bash-preexec.bash (C) 2022, akinomyoga |
| 2 | + |
| 3 | +## @arr[in] precmd_functions |
| 4 | +## @arr[in] preexec_functions |
| 5 | +## The functions registered to these arrays are executed on PRECMD and |
| 6 | +## PREEXEC hooks, respectively. |
| 7 | +## |
| 8 | +## @fn[in] precmd |
| 9 | +## @fn[in] preexec |
| 10 | +## If these functions are defined, they are executed on PRECMD and PREEXEC |
| 11 | +## hooks, respectively, through "precmd_functions" and "preexec_functions". |
| 12 | +## |
| 13 | +## |
| 14 | +## * Integration with bash-preexec.sh (https://github.com/rcaloras/bash-preexec) |
| 15 | +## |
| 16 | +## Although this script works without bash-preexec, it provides a better |
| 17 | +## integration with bash-preexec when bash-preexec is loaded. The |
| 18 | +## integration relies on the following public API of bash-preexec. |
| 19 | +## |
| 20 | +## @fn __bp_precmd_invoke_functions lastexit lastarg |
| 21 | +## @fn __bp_preexec_invoke_functions lastexit lastarg this_command |
| 22 | +## @fn __bp_uninstall |
| 23 | +## @var __bp_trapdebug_string |
| 24 | +## @var __bp_install_string |
| 25 | + |
| 26 | +function ble/contrib/bash-preexec/add-convenience-functions { |
| 27 | + ble/array#remove precmd_functions precmd |
| 28 | + ble/array#remove preexec_functions preexec |
| 29 | + ble/array#push precmd_functions precmd |
| 30 | + ble/array#push preexec_functions preexec |
| 31 | +} |
| 32 | + |
| 33 | +function ble/contrib/bash-preexec/precmd.hook { |
| 34 | + local __lastexit=$? __lastarg=$_ |
| 35 | + |
| 36 | + # Emulate bash-preexec variables |
| 37 | + __bp_last_ret_value=$__lastexit |
| 38 | + BP_PIPESTATUS=("${BLE_PIPESTATUS[@]}") |
| 39 | + |
| 40 | + # local __bp_blesh_invoking_through_blesh=1 # XXX |
| 41 | + if ble/is-function __bp_precmd_invoke_functions; then |
| 42 | + __bp_precmd_invoke_functions "$__lastexit" "$__lastarg" |
| 43 | + else |
| 44 | + # For older bash-preexec.sh / without bash-preexec.sh |
| 45 | + local __hook |
| 46 | + for __hook in "${precmd_functions[@]}"; do |
| 47 | + if builtin type -t "$__hook" &>/dev/null; then |
| 48 | + ble/util/setexit "$__lastexit" "$__lastarg" |
| 49 | + "$__hook" |
| 50 | + fi |
| 51 | + done |
| 52 | + fi |
| 53 | +} |
| 54 | + |
| 55 | +function ble/contrib/bash-preexec/preexec.hook { |
| 56 | + local __lastexit=$? __lastarg=$_ __this_command=$1 |
| 57 | + __bp_last_argument_prev_command=$__lastarg |
| 58 | + |
| 59 | + # local __bp_blesh_invoking_through_blesh=1 # XXX |
| 60 | + if ble/is-function __bp_preexec_invoke_functions; then |
| 61 | + __bp_preexec_invoke_functions "$__lastexit" "$__lastarg" |
| 62 | + else |
| 63 | + # For older bash-preexec.sh / without bash-preexec.sh |
| 64 | + local __hook |
| 65 | + for __hook in "${preexec_functions[@]}"; do |
| 66 | + if builtin type -t "$__hook" &>/dev/null; then |
| 67 | + ble/util/setexit "$__lastexit" "$__lastarg" |
| 68 | + "$__hook" "$__this_command" |
| 69 | + fi |
| 70 | + done |
| 71 | + fi |
| 72 | +} |
| 73 | + |
| 74 | +## @fn ble/contrib/bash-preexec/attach.hook |
| 75 | +## Remove bash-preexec hooks |
| 76 | +function ble/contrib/bash-preexec/attach.hook { |
| 77 | + local BP_TRAPDEBUG_STRING=${__bp_trapdebug_string:-'__bp_preexec_invoke_exec "$_"'} |
| 78 | + |
| 79 | + # Remove bash-preexec preexec hook in builtin DEBUG trap. |
| 80 | + local trap_string q="'" Q="'\''" |
| 81 | + ble/util/assign trap_string 'builtin trap -p DEBUG' |
| 82 | + if [[ $trap_string == "trap -- '${BP_TRAPDEBUG_STRING//$q/$Q}' DEBUG" ]]; then |
| 83 | + if [[ ${__bp_trap_string-} ]]; then |
| 84 | + builtin eval -- "builtin $__bp_trap_string" |
| 85 | + else |
| 86 | + builtin trap - DEBUG |
| 87 | + fi |
| 88 | + fi |
| 89 | + |
| 90 | + if ble/is-function __bp_uninstall; then |
| 91 | + __bp_uninstall |
| 92 | + else |
| 93 | + # For older bash-preexec.sh |
| 94 | + |
| 95 | + local BP_INSTALL_STRING=${__bp_install_string:-$'__bp_trap_string="$(trap -p DEBUG)"\ntrap - DEBUG\n__bp_install'} |
| 96 | + local BP_PROMPT_COMMAND_PREFIX=__bp_precmd_invoke_cmd |
| 97 | + local BP_PROMPT_COMMAND_SUFFIX=__bp_interactive_mode |
| 98 | + |
| 99 | + # Remove __bp_install hook from PROMPT_COMMAND |
| 100 | + if [[ ${PROMPT_COMMAND-} == *"$__bp_install_string"* ]]; then |
| 101 | + PROMPT_COMMAND="${PROMPT_COMMAND//$BP_INSTALL_STRING[;$'\n']}" # Edge case of appending to PROMPT_COMMAND |
| 102 | + PROMPT_COMMAND="${PROMPT_COMMAND//$BP_INSTALL_STRING}" |
| 103 | + fi |
| 104 | + |
| 105 | + # Remove precmd hook from PROMPT_COMMAND |
| 106 | + PROMPT_COMMAND=${PROMPT_COMMAND/#$BP_PROMPT_COMMAND_PREFIX$'\n'/$'\n'} |
| 107 | + PROMPT_COMMAND=${PROMPT_COMMAND%$'\n'$BP_PROMPT_COMMAND_SUFFIX} |
| 108 | + PROMPT_COMMAND=${PROMPT_COMMAND#$'\n'} |
| 109 | + |
| 110 | + # Remove preexec hook in the DEBUG trap |
| 111 | + local q="'" Q="'\''" trap_string |
| 112 | + ble/util/assign trap_string 'trap -p DEBUG' |
| 113 | + if [[ $trap_string == "trap -- '${__bp_trapdebug_string//$q/$Q}' DEBUG" ]]; then |
| 114 | + if [[ ${__bp_trap_string-} ]]; then |
| 115 | + eval -- "$__bp_trap_string" |
| 116 | + else |
| 117 | + trap - DEBUG |
| 118 | + fi |
| 119 | + fi |
| 120 | + fi |
| 121 | +} |
| 122 | + |
| 123 | +## @fn ble/contrib/bash-preexec/detach.hook |
| 124 | +function ble/contrib/bash-preexec/detach.hook { |
| 125 | + # Reinstall bash-preexec hooks |
| 126 | + local BP_INSTALL_STRING=${__bp_install_string-} |
| 127 | + [[ ! $BP_INSTALL_STRING ]] && ble/is-function __bp_install && |
| 128 | + BP_INSTALL_STRING=$'__bp_trap_string="$(trap -p DEBUG)"\ntrap - DEBUG\n__bp_install' |
| 129 | + |
| 130 | + builtin eval -- "$__bp_install_string" |
| 131 | + |
| 132 | + # Note: 重複して登録される (古い bash-preexec.sh) かもしれないし、全 |
| 133 | + # く登録されない (bash-preexec.sh をロードしていない時) かもしれない |
| 134 | + # ので、ble.sh 側で末尾で一回呼び出す形に修正する。 |
| 135 | + ble/contrib/bash-preexec/add-convenience-functions |
| 136 | +} |
| 137 | + |
| 138 | +ble/contrib/bash-preexec/add-convenience-functions |
| 139 | +blehook PRECMD-+=ble/contrib/bash-preexec/precmd.hook |
| 140 | +blehook PREEXEC-+=ble/contrib/bash-preexec/preexec.hook |
| 141 | +blehook ATTACH-+=ble/contrib/bash-preexec/attach.hook |
| 142 | +blehook DETACH-+=ble/contrib/bash-preexec/detach.hook |
| 143 | +if [[ ${bp_imported-${__bp_imported-}} ]]; then |
| 144 | + ble/contrib/bash-preexec/attach.hook |
| 145 | +fi |
| 146 | + |
| 147 | +# XXX: 以下は uninstall で削除しきれなかった時の為の保険。今の所不要に思われる。 |
| 148 | +# __bp_blesh_check() { |
| 149 | +# if [[ $BLE_ATTACHED && ! ${__bp_blesh_invoking_through_blesh-} ]]; then |
| 150 | +# ble/contrib/bash-preexec/attach.hook |
| 151 | +# fi |
| 152 | +# } |
| 153 | +# precmd_function+=(__bp_blesh_check) |
| 154 | +# preexec_function+=(__bp_blesh_check) |
0 commit comments