-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Install bash-preexec after our session is started.
- Invoke our install as part of PROMPT_COMMAND. This allows bash-preexec to be included at any point in our configuration and it should be invoked last. This makes sure we always have access to the DEBUG trap and that PROMPT_COMMAND is most likely untampered with. - Should adress #21 and the occasional issue that gets created because bash-preexec is included improperly.
- Loading branch information
Showing
3 changed files
with
81 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
# | ||
# | ||
# 'preexec' functions are executed before each interactive command is | ||
# executed, with the interactive command as its argument. The 'precmd' | ||
# executed, with the interactive command as its argument. The 'precmd' | ||
# function is executed before each prompt is displayed. | ||
# | ||
# Author: Ryan Caloras ([email protected]) | ||
|
@@ -44,6 +44,10 @@ __bp_imported="defined" | |
# functions, should they want it. | ||
__bp_last_command_ret_value="$?" | ||
|
||
# Command to set our preexec trap. It's invoked once via | ||
# PROMPT_COMMAND and then removed. | ||
__bp_trap_install_string="trap '__bp_preexec_invoke_exec' DEBUG;" | ||
|
||
# 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. | ||
|
@@ -137,7 +141,7 @@ __bp_preexec_invoke_exec() { | |
# __bp_delay_install checks if we're in test. Needed for bats to run. | ||
# Prevents preexec from being invoked for functions in PS1 | ||
if [[ ! -t 1 && -z "$__bp_delay_install" ]]; then | ||
return | ||
return | ||
fi | ||
|
||
if [[ -n "$COMP_LINE" ]]; then | ||
|
@@ -192,14 +196,33 @@ __bp_preexec_invoke_exec() { | |
done | ||
} | ||
|
||
# Execute this to set up preexec and precmd execution. | ||
__bp_preexec_and_precmd_install() { | ||
# Returns PROMPT_COMMAND with a semicolon appended | ||
# if it doesn't already have one. | ||
__bp_prompt_command_with_semi_colon() { | ||
# Take our existing prompt command and append a semicolon to it | ||
# if it doesn't already have one. | ||
local existing_prompt_command | ||
|
||
# Make sure this is bash that's running this and return otherwise. | ||
if [[ -z "$BASH_VERSION" ]]; then | ||
return 1; | ||
if [[ -n "$PROMPT_COMMAND" ]]; then | ||
existing_prompt_command=${PROMPT_COMMAND%${PROMPT_COMMAND##*[![:space:]]}} | ||
existing_prompt_command=${existing_prompt_command%;} | ||
existing_prompt_command=${existing_prompt_command/%/;} | ||
else | ||
existing_prompt_command="" | ||
fi | ||
|
||
echo -n "$existing_prompt_command" | ||
} | ||
|
||
__bp_install() { | ||
|
||
# Remove setting our trap from PROMPT_COMMAND | ||
PROMPT_COMMAND="${PROMPT_COMMAND//$__bp_trap_install_string}" | ||
|
||
# Remove this function from our PROMPT_COMMAND | ||
PROMPT_COMMAND="${PROMPT_COMMAND//__bp_install;}" | ||
|
||
|
||
# Exit if we already have this installed. | ||
if [[ "$PROMPT_COMMAND" == *"__bp_precmd_invoke_cmd"* ]]; then | ||
return 1; | ||
|
@@ -208,34 +231,52 @@ __bp_preexec_and_precmd_install() { | |
# Adjust our HISTCONTROL Variable if needed. | ||
__bp_adjust_histcontrol | ||
|
||
|
||
# Set so debug trap will work be invoked in subshells. | ||
set -o functrace > /dev/null 2>&1 | ||
shopt -s extdebug > /dev/null 2>&1 | ||
|
||
# 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=${PROMPT_COMMAND%${PROMPT_COMMAND##*[![:space:]]}} | ||
existing_prompt_command=${existing_prompt_command%;} | ||
existing_prompt_command=${existing_prompt_command/%/;} | ||
else | ||
existing_prompt_command="" | ||
fi | ||
local existing_prompt_command | ||
existing_prompt_command=$(__bp_prompt_command_with_semi_colon) | ||
|
||
# Finally install our traps. | ||
# Install our hooks in PROMPT_COMMAND to allow our trap to know when we've | ||
# actually entered something. | ||
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) | ||
|
||
# Since this is in PROMPT_COMMAND, invoke any precmd functions we have defined. | ||
__bp_precmd_invoke_cmd | ||
# Put us in interactive mode for our first command. | ||
__bp_interactive_mode | ||
} | ||
|
||
# Sets our trap and __bp_install as part of our PROMPT_COMMAND to install | ||
# after our session has started. This allows bash-preexec to be inlucded | ||
# at any point in our bash profile. Ideally we could set our trap inside | ||
# __bp_install, but if a trap already exists it'll only set locally to | ||
# the function. | ||
__bp_install_after_session_init() { | ||
|
||
# Make sure this is bash that's running this and return otherwise. | ||
if [[ -z "$BASH_VERSION" ]]; then | ||
return 1; | ||
fi | ||
|
||
local existing_prompt_command | ||
existing_prompt_command=$(__bp_prompt_command_with_semi_colon) | ||
|
||
# Add our installation to be done last via our PROMPT_COMMAND. These are | ||
# removed by __bp_install when it's invoked so it only runs once. | ||
PROMPT_COMMAND="${existing_prompt_command} $__bp_trap_install_string __bp_install;" | ||
} | ||
|
||
# Run our install so long as we're not delaying it. | ||
if [[ -z "$__bp_delay_install" ]]; then | ||
__bp_preexec_and_precmd_install | ||
__bp_install_after_session_init | ||
fi; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters