sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

bash-preexec.bash (6014B)


      1 # ble/contrib/integration/bash-preexec.bash (C) 2022-2023, 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/integration:bash-preexec/add-convenience-functions {
     27   ble/array#remove precmd_functions  precmd
     28   ble/array#remove preexec_functions preexec
     29   ble/array#unshift precmd_functions  precmd
     30   ble/array#unshift preexec_functions preexec
     31 }
     32 
     33 function ble/contrib/integration:bash-preexec/precmd.hook {
     34   local _ble_local_lastexit=$? _ble_local_lastarg=$_
     35 
     36   # Emulate bash-preexec variables
     37   __bp_last_ret_value=$_ble_local_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 "$_ble_local_lastexit" "$_ble_local_lastarg"
     43   else
     44     # For older bash-preexec.sh / without bash-preexec.sh
     45     local _ble_local_hook
     46     for _ble_local_hook in "${precmd_functions[@]}"; do
     47       if builtin type -t "$_ble_local_hook" &>/dev/null; then
     48         ble/util/setexit "$_ble_local_lastexit" "$_ble_local_lastarg"
     49         "$_ble_local_hook"
     50       fi
     51     done
     52   fi
     53 }
     54 
     55 function ble/contrib/integration:bash-preexec/preexec.hook {
     56   local _ble_local_lastexit=$? _ble_local_lastarg=$_ _ble_local_command=$1
     57   __bp_last_argument_prev_command=$_ble_local_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 "$_ble_local_lastexit" "$_ble_local_lastarg"
     62   else
     63     # For older bash-preexec.sh / without bash-preexec.sh
     64     local _ble_local_hook
     65     for _ble_local_hook in "${preexec_functions[@]}"; do
     66       if builtin type -t "$_ble_local_hook" &>/dev/null; then
     67         ble/util/setexit "$_ble_local_lastexit" "$_ble_local_lastarg"
     68         "$_ble_local_hook" "$_ble_local_command"
     69       fi
     70     done
     71   fi
     72 }
     73 
     74 ## @fn ble/contrib/integration:bash-preexec/attach.hook
     75 ##   Remove bash-preexec hooks
     76 function ble/contrib/integration: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/integration:bash-preexec/detach.hook
    124 function ble/contrib/integration: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/integration:bash-preexec/add-convenience-functions
    136 }
    137 
    138 ble/contrib/integration:bash-preexec/add-convenience-functions
    139 blehook PRECMD!=ble/contrib/integration:bash-preexec/precmd.hook
    140 blehook PREEXEC!=ble/contrib/integration:bash-preexec/preexec.hook
    141 blehook ATTACH!=ble/contrib/integration:bash-preexec/attach.hook
    142 blehook DETACH!=ble/contrib/integration:bash-preexec/detach.hook
    143 if [[ ${bp_imported-${__bp_imported-}} ]]; then
    144   ble/contrib/integration: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/integration:bash-preexec/attach.hook
    151 #   fi
    152 # }
    153 # precmd_function+=(__bp_blesh_check)
    154 # preexec_function+=(__bp_blesh_check)