As others have pointed out, color codes in PS1 should be bracketed by \[ and \] to avoid them taking up horizontal space. I've added the necessary code to .bashrc:
highlight()
{
if [ -x /usr/bin/tput ]
then
printf '\['
tput bold
printf '\]'
printf '\['
tput setaf $1
printf '\]'
fi
shift
printf -- "$@"
if [ -x /usr/bin/tput ]
then
printf '\['
tput sgr0
printf '\]'
fi
}
highlight_error()
{
highlight 1 "$@"
}
The last function is used in PS1 in both normal and escaped command substitutions to be able to change the string based on the result of the previous command:
# Exit code
PS1="\$(exit_code=\${?#0}
highlight_error \"\${exit_code}\${exit_code:+ }\")"
...
if [ "$USER" == 'root' ]
then
PS1="${PS1}$(highlight_error '\u')"
else
PS1="${PS1}\u"
fi
The issue is then that the escaped brackets are output as literals, so my prompt looks like this after running a command which doesn't exist:
\[\]\[\]127 \[\]user@machine:/path
$
Wrapping the escaped highlight_error in printf %b didn't help. How can I fix the output so that I can use the functions for both normal and escaped command substitutions?
