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?

pt12lol
  • 158
  • 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 03 '14 at 11:54
  • works great! why didn't you answered but only commented? – pt12lol Aug 03 '14 at 12:04
  • @Groxxda yes, this is the answer - so make it a full answer – Volker Siegel Aug 03 '14 at 12:45
  • I've got one another problem. After upgrade by @Groxxda, my .bashrc PS1 definition looks like this one: http://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 03 '14 at 16:19
  • The original question is a duplicate of http://unix.stackexchange.com/questions/28827/why-is-my-bash-prompt-getting-bugged-when-i-browse-the-history. 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 \[…\]. – Gilles 'SO- stop being evil' Aug 03 '14 at 20:45
  • Your unescaped sequences are still breaking your term... You are better off starting with a simple prompt, and building it up gradually, as you understand how it works. – jasonwryan Aug 03 '14 at 20:45
  • @jasonwryan, which one sequences are still unescaped? I want to have format [login@computername]... etc. – pt12lol Aug 03 '14 at 21:19
  • [login@hostname] is the basic prompt: see https://wiki.archlinux.org/index.php/Color_Bash_Prompt#Regular_user – jasonwryan Aug 03 '14 at 21:22
  • Ok, but there are still no colors. If I understand well, I have to escape all color tags, because they don't print any sign, but only send information about color and caret is missed. So I did this: http://pastebin.com/4exfRRN9. But there are still two missing fields... What should I also escape? – pt12lol Aug 03 '14 at 21:31
  • Try removing the duplicate \]s in your prompt. Also which fields are missing? – groxxda Aug 03 '14 at 22:42
  • Ok. your solution works. But I don't know why... but anyway - thanks a lot! – pt12lol Aug 04 '14 at 00:09

2 Answers2

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.

Volker Siegel
  • 17,283
  • I moved my .bashrc file to Ubuntu and some strange problem appeared again. http://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 - https://github.com/pt12lol/dotfiles/blob/master/.bashrc. – pt12lol Feb 15 '15 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.

mikeserv
  • 58,310