Skip to content

Commit

Permalink
Store and unset IFS for arrays and read
Browse files Browse the repository at this point in the history
- Fix for #64
- bash-preexec would break if IFS was changed. It should be default for
  the way we're using arrays and read.
  • Loading branch information
Ryan Caloras committed Jan 7, 2018
1 parent e81e7bf commit 2b86ce9
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions bash-preexec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ __bp_last_argument_prev_command="$_"
__bp_inside_precmd=0
__bp_inside_preexec=0

# Helper functions for handling IFS which must be default
# for using read and working with bash arrays
__bp_store_and_unset_ifs() {
${IFS+"false"} && unset __bp__old_ifs || __bp_old_ifs="$IFS"
unset IFS
}

__bp_restore_ifs() {
${__bp_old_ifs+"false"} && unset IFS || IFS="$__bp_old_ifs"
}

# 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.
Expand Down Expand Up @@ -100,6 +111,7 @@ __bp_precmd_invoke_cmd() {

# Invoke every function defined in our function array.
local precmd_function
__bp_store_and_unset_ifs
for precmd_function in "${precmd_functions[@]}"; do

# Only execute this function if it actually exists.
Expand All @@ -109,6 +121,7 @@ __bp_precmd_invoke_cmd() {
$precmd_function
fi
done
__bp_restore_ifs
}

# Sets a return value in $?. We may want to get access to the $? variable in our
Expand All @@ -126,15 +139,18 @@ __bp_in_prompt_command() {
local trimmed_arg
trimmed_arg=$(__bp_trim_whitespace "$1")

__bp_store_and_unset_ifs
local command
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
__bp_restore_ifs
return 0
fi
done
__bp_restore_ifs

return 1
}
Expand Down Expand Up @@ -180,7 +196,6 @@ __bp_preexec_invoke_exec() {
__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 :/
Expand All @@ -189,7 +204,7 @@ __bp_preexec_invoke_exec() {
fi

local this_command
this_command=$(HISTTIMEFORMAT= builtin history 1 | { read -r _ this_command; echo "$this_command"; })
this_command=$(HISTTIMEFORMAT= builtin history 1 | { IFS=" " read -r _ this_command; echo "$this_command"; })

# Sanity check to make sure we have something to invoke our function with.
if [[ -z "$this_command" ]]; then
Expand All @@ -204,6 +219,7 @@ __bp_preexec_invoke_exec() {
local preexec_function
local preexec_function_ret_value
local preexec_ret_value=0
__bp_store_and_unset_ifs
for preexec_function in "${preexec_functions[@]}"; do

# Only execute each function if it actually exists.
Expand All @@ -217,6 +233,7 @@ __bp_preexec_invoke_exec() {
fi
fi
done
__bp_restore_ifs

# Restore the last argument of the last executed command, and set the return
# value of the DEBUG trap to be the return code of the last preexec function
Expand Down

0 comments on commit 2b86ce9

Please sign in to comment.