| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 | 
							- #!/bin/bash
 - #
 - # bash-preexec.sh -- Bash support for ZSH-like 'preexec' and 'precmd' functions.
 - # https://github.com/rcaloras/bash-preexec
 - #
 - #
 - # 'preexec' functions are executed before each interactive command is
 - # executed, with the interactive command as its argument.  The 'precmd'
 - # function is executed before each prompt is displayed.
 - #
 - # Author: Ryan Caloras (ryan@bashhub.com)
 - # Forked from Original Author: Glyph Lefkowitz
 - #
 - # V0.2.1
 - #
 - 
 - # General Usage:
 - #
 - #  1. Source this file at the end of your bash profile so as not to interfere
 - #     with anything else that's using PROMPT_COMMAND.
 - #
 - #  2. Add any precmd or preexec functions by appending them to their arrays:
 - #       e.g.
 - #       precmd_functions+=(my_precmd_function)
 - #       precmd_functions+=(some_other_precmd_function)
 - #
 - #       preexec_functions+=(my_preexec_function)
 - #
 - #  3. If you have anything that's using the Debug Trap, change it to use
 - #     preexec. (Optional) change anything using PROMPT_COMMAND to now use
 - #     precmd instead.
 - #
 - #  Note: This module requires two bash features which you must not otherwise be
 - #  using: the "DEBUG" trap, and the "PROMPT_COMMAND" variable. prexec_and_precmd_install
 - #  will override these and if you override one or the other this will most likely break.
 - 
 - # Avoid duplicate inclusion
 - if [[ "$__bp_imported" == "defined" ]]; then
 -     return 0
 - fi
 - __bp_imported="defined"
 - 
 - 
 - # Remove ignorespace and or replace ignoreboth from HISTCONTROL
 - # so we can accurately invoke preexec with a command from our
 - # history even if it starts with a space.
 - __bp_adjust_histcontrol() {
 -     local histcontrol
 -     histcontrol="${HISTCONTROL//ignorespace}"
 -     # Replace ignoreboth with ignoredups
 -     if [[ "$histcontrol" == *"ignoreboth"* ]]; then
 -         histcontrol="ignoredups:${histcontrol//ignoreboth}"
 -     fi;
 -     export HISTCONTROL="$histcontrol"
 - }
 - 
 - # This variable describes whether we are currently in "interactive mode";
 - # i.e. whether this shell has just executed a prompt and is waiting for user
 - # input.  It documents whether the current command invoked by the trace hook is
 - # run interactively by the user; it's set immediately after the prompt hook,
 - # and unset as soon as the trace hook is run.
 - __bp_preexec_interactive_mode=""
 - 
 - __bp_trim_whitespace() {
 -     local var=$@
 -     var="${var#"${var%%[![:space:]]*}"}"   # remove leading whitespace characters
 -     var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
 -     echo -n "$var"
 - }
 - 
 - # This function is installed as part of the PROMPT_COMMAND;
 - # It sets a variable to indicate that the prompt was just displayed,
 - # to allow the DEBUG trap to know that the next command is likely interactive.
 - __bp_interactive_mode() {
 -     __bp_preexec_interactive_mode="on";
 - }
 - 
 - 
 - # This function is installed as part of the PROMPT_COMMAND.
 - # It will invoke any functions defined in the precmd_functions array.
 - __bp_precmd_invoke_cmd() {
 - 
 -     # Should be available to each precmd function, should it want it.
 -     local ret_value="$?"
 - 
 -     # For every function defined in our function array. Invoke it.
 -     local precmd_function
 -     for precmd_function in ${precmd_functions[@]}; do
 - 
 -         # Only execute this function if it actually exists.
 -         if [[ -n $(type -t $precmd_function) ]]; then
 -             __bp_set_ret_value $ret_value
 -             $precmd_function
 -         fi
 -     done
 - }
 - 
 - # Sets a return value in $?. We may want to get access to the $? variable in our
 - # precmd functions. This is available for instance in zsh. We can simulate it in bash
 - # by setting the value here.
 - __bp_set_ret_value() {
 -     return $1
 - }
 - 
 - __bp_in_prompt_command() {
 - 
 -     local prompt_command_array
 -     IFS=';' read -ra prompt_command_array <<< "$PROMPT_COMMAND"
 - 
 -     local trimmed_arg
 -     trimmed_arg=$(__bp_trim_whitespace "$1")
 - 
 -     local prompt_command_function
 -     for command in "${prompt_command_array[@]}"; do
 -         local trimmed_command
 -         trimmed_command=$(__bp_trim_whitespace "$command")
 -         # Only execute each function if it actually exists.
 -         if [[ "$trimmed_command" == "$trimmed_arg" ]]; then
 -             return 0
 -         fi
 -     done
 - 
 -     return 1
 - }
 - 
 - # This function is installed as the DEBUG trap.  It is invoked before each
 - # interactive prompt display.  Its purpose is to inspect the current
 - # environment to attempt to detect if the current command is being invoked
 - # interactively, and invoke 'preexec' if so.
 - __bp_preexec_invoke_exec() {
 - 
 -     if [[ -n "$COMP_LINE" ]]
 -     then
 -         # We're in the middle of a completer.  This obviously can't be
 -         # an interactively issued command.
 -         return
 -     fi
 -     if [[ -z "$__bp_preexec_interactive_mode" ]]
 -     then
 -         # We're doing something related to displaying the prompt.  Let the
 -         # prompt set the title instead of me.
 -         return
 -     else
 -         # If we're in a subshell, then the prompt won't be re-displayed to put
 -         # us back into interactive mode, so let's not set the variable back.
 -         # In other words, if you have a subshell like
 -         #   (sleep 1; sleep 2)
 -         # You want to see the 'sleep 2' as a set_command_title as well.
 -         if [[ 0 -eq "$BASH_SUBSHELL" ]]
 -         then
 -             __bp_preexec_interactive_mode=""
 -         fi
 -     fi
 - 
 -     if  __bp_in_prompt_command "$BASH_COMMAND"; then
 -         # If we're executing something inside our prompt_command then we don't
 -         # want to call preexec. Bash prior to 3.1 can't detect this at all :/
 - 
 -         __bp_preexec_interactive_mode=""
 -         return
 -     fi
 - 
 -     local this_command="$(HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g")";
 - 
 -     # Sanity check to make sure we have something to invoke our function with.
 -     if [[ -z "$this_command" ]]; then
 -         return
 -     fi
 - 
 -     # If none of the previous checks have returned out of this function, then
 -     # the command is in fact interactive and we should invoke the user's
 -     # preexec functions.
 - 
 -     # For every function defined in our function array. Invoke it.
 -     local preexec_function
 -     for preexec_function in "${preexec_functions[@]}"; do
 - 
 -         # Only execute each function if it actually exists.
 -         if [[ -n $(type -t $preexec_function) ]]; then
 -             $preexec_function "$this_command"
 -         fi
 -     done
 - }
 - 
 - # Execute this to set up preexec and precmd execution.
 - __bp_preexec_and_precmd_install() {
 - 
 -     # Make sure this is bash that's running this and return otherwise.
 -     if [[ -z "$BASH_VERSION" ]]; then
 -         return 1;
 -     fi
 - 
 -     # Exit if we already have this installed.
 -     if [[ "$PROMPT_COMMAND" == *"__bp_precmd_invoke_cmd"* ]]; then
 -         return 1;
 -     fi
 - 
 -     # Adjust our HISTCONTROL Variable if needed.
 -     __bp_adjust_histcontrol
 - 
 -     # Take our existing prompt command and append a semicolon to it
 -     # if it doesn't already have one.
 -     local existing_prompt_command
 - 
 -     if [[ -n "$PROMPT_COMMAND" ]]; then
 -         existing_prompt_command=$(echo "$PROMPT_COMMAND" | sed '/; *$/!s/$/;/')
 -     else
 -         existing_prompt_command=""
 -     fi
 - 
 -     # Finally install our traps.
 -     PROMPT_COMMAND="__bp_precmd_invoke_cmd; ${existing_prompt_command} __bp_interactive_mode;"
 -     trap '__bp_preexec_invoke_exec' DEBUG;
 - 
 -     # Add two functions to our arrays for convenience
 -     # of definition.
 -     precmd_functions+=(precmd)
 -     preexec_functions+=(preexec)
 - }
 - 
 - # Run our install so long as we're not delaying it.
 - if [[ -z "$__bp_delay_install" ]]; then
 -     __bp_preexec_and_precmd_install
 - fi;
 
 
  |