Reverse-search in CLI: messed up output afterwards [duplicate]
See my edit below, this is not totally a duplicate of Shell prompt customization and cmd behavior
My reverse-search
function in the CLI is broken and I don't know how to fix it back...
When I hit ctrl+r and search a command I did earlier, find it then press the right arrow key to use it, the output is broken. Here is an example:
# I reverse-searched the word "test" then pressed right arrow
yoshiji@x1carbon:~/path/to/git/folder (master) $ch)`test': rake test
# ^^^^^^^^^^ weird output
# ^ cursor right there
It also "shifts" my cursor to a different position. If I press enter, the right command is executed (rake test
in this case) so it means the text displayed is not the same as what is actually executed.
I know this is most-likely related to my PS1
export in my ~/.bashrc
, so here are the last lines of this file:
# Git branch in prompt.
git_branch() {
branch=$(__git_ps1 2> /dev/null)
if [ "$branch" = " (master)" ]; then
echo -e "\033[33m${branch}\033[00m" # yellow
elif [ "$branch" = "" ]; then
echo -e "\033[90m (no git)\033[00m" # red
else
echo -e "\033[32m${branch}\033[00m" # green
fi
}
PS1='\u@\h:\w$(git_branch) \$ '
This is something I wrote to displays the git branch in orange (if master
branch) or else in green (or no git
in gray).
Do you guys have any idea on what is causing this weird behavior?
Edit: This is a different problem from the possible duplicate in the way that I am using echo -e "some string"
to return a string having color+name of the git branch from the function git_branch()
. Using echo -e
does not escape the characters \[
and \]
(try it yourself in your CLI: echo -e "\[\033[33m\]test"
).
Ideally, I would like to keep those conditional colors based on the branch's presence & name (gray if no branch, orange if master, else green).
Solution 1:
Wrap the color sequences in readline escapes like so:
echo -e "\001\033[33m\002${branch}\001\033[00m\002" # yellow
echo -e "\001\033[90m\002 (no git)\001\033[00m\002" # red
echo -e "\001\033[32m\002${branch}\001\033[00m\002" # green
The readline escapes are \001
at the start of a non-printing sequence, and \002
at the end. These are equivalent to \[
and \]
, respectively, in the PS1 string.
Source: archemiro's answer on bash prompt and echoing colors inside a function - Stack Overflow
This is my answer from another question with the code changed.
Solution 2:
When you put colour codes in your prompt you have to add extra markers to let the terminal know that you have invisible characters in the prompt
Change
echo -e "\033[33m${branch}\033[00m" # yellow
to
echo -e "\[\033[33m\]${branch}\[\033[00m\]" # yellow
# .......^^........^^.........^^........^^
and so on
See Controlling the Prompt in the bash manual.