6

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).

marked as duplicate by muru command-line May 13 '18 at 7:52

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

8

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.

  • @MrYoshiji Glad I could help! – wjandrea May 11 '18 at 17:37
3

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.

  • I did this but it does not escape, it just adds the \[ and \] to the final result: \[\] (master)\[\] $. I think this is because I use echo to output the string then capture it via a call to the function in the PS1 assignment... – MrYoshiji May 11 '18 at 15:28
  • After further investigation, it is in fact the use of echo -e that prints out the \[ and \] that should be escaped for the PS1... – MrYoshiji May 11 '18 at 15:38
  • You could ignore the \[ and \] and add a newline before the \$, then the "weird output" problem won't bother you anymore -- that's what I do, but I like the $ at the left of the screen anyway. – glenn jackman May 11 '18 at 15:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.