3

I want to have really complex prompt. It should contains login, computer name, date, time, working directory, result of last command and new line symbol. I want to color each item as well. So I inserted into my .bashrc some kind of monster like this one:

# login and computer name
PS1='[\e[1;37m\]\u\e[m\]@\e[1;32m\]\h\e[m\]] '
# date, time and working directory
PS1=$PS1'[\e[1;34m\]\D{%Y-%m-%d} \e[1;35m\]\t\e[m\]] \e[1;33m\]\w\e[m\] '
# result of last command and command prompt in new line
PS1=$PS1'\e[1;31m\]${?#0}\e[m\]\n \e[1;36m\]\$\e[m\] '

I do know it is terrible solution, but I have too little experience with bash to improve this. But this is not the only one problem.

 $ aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bash: bbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: command not found...

After the last a I pressed Home key, but visual caret didn't go to the beginning of the command. As you can see, actual caret went to the beginning. Why this occurred? How can I improve my command prompt in my .bashrc?


Update:

After using @Groxxda advice, I've got one another problem. My .bashrc PS1 definition looks like this one. Described issue doesn't occur now. But if in my command history I have ls and before this I have cat script.sh, and if I push arrow up twice, I have got command like cat scls and buffer has only two signs (only ls). Why this occurs? How can I manage this?

11
  • 2
    Check your \[ \] escapes. This tells bash that the content between does not print visible characters. You should put them around the color codes.
    – groxxda
    Aug 3, 2014 at 11:54
  • works great! why didn't you answered but only commented?
    – pt12lol
    Aug 3, 2014 at 12:04
  • @Groxxda yes, this is the answer - so make it a full answer Aug 3, 2014 at 12:45
  • I've got one another problem. After upgrade by @Groxxda, my .bashrc PS1 definition looks like this one: pastebin.com/EZDn6VkP. Described issue doesn't occurs now. But if in my command history I have ls and before this I have cat script.sh, and if I push arrow twice, I have got command like cat scls and buffer has only two signs (only ls). Why this occurs? How can I manage this?
    – pt12lol
    Aug 3, 2014 at 16:19
  • The original question is a duplicate of unix.stackexchange.com/questions/28827/…. I'm not sure I understand the duplicate, but it looks like it's still the same issue: you need to wrap all zero-width parts of the prompt in \[…\]. Aug 3, 2014 at 20:45

2 Answers 2

3

You need to enclose invisible parts of the prompt text in \[ and \].
That is used by bash to calculate the length of the complete prompt, so it can determine where the cursor will be after printing it.
For example, ANSI color escape codes are invisible - they change the color for text that will be output later. They need to be enclosed like this:

\e[1;35m becomes \[\e[1;35m\]

In your update, you write that this helped, but that there is another problem:
the screen does not get cleared at the right locations if you use the history with Up/Down.

This is just another aspect of the first problem: The calculation of the prompt text length is wrong.

Let's take a look at the corrected prompt text from your link:

# login and computer name                                                      
PS1='[\e[\[1;37m\]\]\u\e[\[m\]\]@\e[\[1;32m\]\]\h\e[\[m\]\]] '                  
# date, time                                                                    
PS1=$PS1'[\e[\[1;34m\]\]\D{%Y-%m-%d} \e[\[1;35m\]\]\t\e[\[m\]\]] '              
# working directory and result of last command                                  
PS1=$PS1'\e[\[1;33m\]\]\w\e[\[m\]\] \e[\[1;31m\]\]${?#0}\e[\[m\]\]\n '          
# command prompt                                                                
PS1=$PS1'\e[\[1;36m\]\]\$\e[\[m\]\] '

The problem is that the \[ and \] are not enclosing the whole color escape sequences:
The prompt starts with

[\e[\[1;37m\]\]... 

The color escape sequence in this is \e[1;37m. So the escape character \e, and the [ are outside. At least the [ will be counted as visible. Also, there are two closing \] - it may not cause a problem, but is at least confusing - they can not be nested.
The correct way to write it is:

[\[\e[1;37m\]... 

The other color escape sequences have the same problem.

1
  • I moved my .bashrc file to Ubuntu and some strange problem appeared again. postimg.org/image/7auk9ziex - here is a screenshot and problematic sign is that one yellow in the end of the first line. If you pay attention, there are two signs in one slot - that some strange one and '~'. What is the problem? How can I help? .bashrc is still in my repo in github - github.com/pt12lol/dotfiles/blob/master/.bashrc.
    – pt12lol
    Feb 15, 2015 at 11:30
1

You should modularize this some - it would make it much easier to track:

CS='\[\033[1;3' CE='m\]'
WT=${CS}7${CE} LB=${CS}6${CE} PR=${CS}5${CE} \
DB=${CS}4${CE} YL=${CS}3${CE} GN=${CS}2${CE} RD=${CS}1${CE} 
CE='\[\033[m\]' CS=

Now you do your things:

# login and computer name                                                      
PS1="[${WT}\u${CE}@${GN}\h${CE}] "

...

And so on.. You see? It's a little easier to tell what's going on that way.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .