document updated 13 years ago, on Mar 20, 2012
# Cause all STDIN to be hilighted.
# To use this, source it from your ~/.bashrc.
# To change the color that your STDIN text is displayed in, add an ANSI code to the end of your
# prompt.
#
# Example:
# export PS1='\[\033[0m\]\u@\h:\w\$ \[\033[102;30m\]'
# This was inspired by http://www.twistedmatrix.com/users/glyph/preexec.bash.txt
# http://superuser.com/questions/175799
# BUGS:
# - bleeding happens when:
# - Ctrl-L is used to clear the screen
# - you backspace
# - you do a syntax error (for example, open a single-quote, but don't close it)
function trap_install () {
# *BOTH* of these options need to be set for the DEBUG trap to be invoked
# in ( ) subshells. This smells like a bug in bash to me. The null stderr
# redirections are to quiet errors on bash2.05 (i.e. OSX's default shell)
# where the options can't be set, and it's impossible to inherit the trap
# into subshells.
set -o functrace > /dev/null 2>&1
shopt -s extdebug > /dev/null 2>&1
# Finally, install the actual traps.
#PROMPT_COMMAND="${PROMPT_COMMAND};preexec_invoke_cmd"
PROMPT_COMMAND="preexec_invoke_cmd"
trap 'preexec_invoke_exec' DEBUG
}
# This function is installed as the PROMPT_COMMAND; it is invoked before each
# interactive prompt display. It sets a variable to indicate that the prompt
# was just displayed, to allow the DEBUG trap, below, to know that the next
# command is likely interactive.
function preexec_invoke_cmd () {
preexec_interactive_mode="yes"
}
# 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.
function preexec_invoke_exec () {
# We're in the middle of tab-completion. Don't do anything.
if [[ -n "$COMP_LINE" ]]; then return; fi
echo -ne '\033[0m'
return
if [[ -z "$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
preexec_interactive_mode=""
fi
fi
if [[ "preexec_invoke_cmd" == "$BASH_COMMAND" ]]
then
# Sadly, there's no cleaner way to detect two prompts being displayed
# one after another. This makes it important that PROMPT_COMMAND
# remain set _exactly_ as below in preexec_install. Let's switch back
# out of interactive mode and not trace any of the commands run in
# precmd.
# Given their buggy interaction between BASH_COMMAND and debug traps,
# versions of bash prior to 3.1 can't detect this at all.
preexec_interactive_mode=""
return
fi
# If none of the previous checks have earlied out of this function, then
# the command is in fact interactive, and this is the equivlant point of zsh's preexec.
echo -en '\033[0m'
}
trap_install