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
rcaloras committed Jan 9, 2018
1 parent e81e7bf commit 0183fd8
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 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,15 +111,19 @@ __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
__bp_restore_ifs

# Only execute this function if it actually exists.
# Test existence of functions with: declare -[Ff]
if type -t "$precmd_function" 1>/dev/null; then
__bp_set_ret_value "$__bp_last_ret_value" "$__bp_last_argument_prev_command"
$precmd_function
fi
__bp_store_and_unset_ifs
done
__bp_restore_ifs
}

# Sets a return value in $?. We may want to get access to the $? variable in our
Expand All @@ -126,15 +141,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 +198,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 +206,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,8 +221,9 @@ __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

__bp_restore_ifs
# Only execute each function if it actually exists.
# Test existence of function with: declare -[fF]
if type -t "$preexec_function" 1>/dev/null; then
Expand All @@ -216,7 +234,9 @@ __bp_preexec_invoke_exec() {
preexec_ret_value="$preexec_function_ret_value"
fi
fi
__bp_store_and_unset_ifs
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 0183fd8

Please sign in to comment.