View Full Version : Color prompts & line-wrapping in bash
Santiago
11-05-2003, 03:14 PM
I've got 10.3, upgrade install, and changed my default shell from tcsh to bash. If I create a custom prompt with color escape sequences in it, line-wrapping on long commands gets messed up. Specifically, if the text entered on the command line exceeds a certain width, it wraps back to the beginning of current line instead of the next line, overwriting what was previously there. (The command itself is fine, just the display is messed up.) Tests at different windows sizes and with different prompts show that the width at which this wrapping takes place seems to be a fixed distance from the right edge of the window and proportional to, though not equal to, the length of the prompt itself. (About two inches for a typical prompt, about half an inch for just a red dollar-sign.) If the window is too narrow, this mangling even affects the prompt itself. I assume it's some sort of carriage-return versus linefeed issue. Does anyone know what's going on?
mervTormel
11-05-2003, 03:16 PM
show us:
$ echo $TERM
ansi
Santiago
11-05-2003, 03:23 PM
Relevant environment variables are set to:
TERM_PROGRAM=Apple_Terminal
TERM=xterm-color
Setting term to ansi causes the lines to wrap onto the next line correctly, as opposed to the current line. However, the first line still wraps too early (though the others are fine). Is it because the characters making up the color-setting sequences are getting counted as part of the line length despite not taking up screen space?
mervTormel
11-05-2003, 03:31 PM
show us:
$ echo $COLUMNS
115
and is it the same as the x dimension of the shell window?
Santiago
11-05-2003, 03:43 PM
I get 132, same as the dimension stated in "Window Settings..." Given that it only wraps oddly on the line with the prompt and not on subsequent ones, I'm inclined to think it's an oddity regarding the escape sequences counting in the line length. Not overwriting the same line was the big issue.
jonbauman
02-07-2005, 01:01 PM
I had the same issue, and I don't think the problem has to do with the TERM variable. In fact, I tried changing it to "ansi" myself, and emacs got all screwed up.
You didn't put the value of PS1 in your original post, so I can only assume you're having the same issues I was, which was failing to mark the ANSI escape sequences as non-printing characters.
Before I had the following value for PS1:
'\e[0;34m\h:\w [\!]\$\e[0m '
which gave me a nice blue prompt of the following form
hostname:working-directory [command-number]$
However, I had the same line-wrapping problem you did. The fix was to insert \[ and \] around the ANSI escapes so that the shell knows not to include them in the line wrapping calculation. This results in the following value for PS1:
'\[\e[0;34m\]\h:\w [\!]\$\[\e[m\] '
AntiGenX
02-07-2005, 01:50 PM
Just for fun, I'm putting my prompt here... feel free to use it. It has one extra component: If the previous command returned anything other than 0 it will display the return value in red.
PS1='\[\e[0;36m\]\h:\[\e[1;37m\]\w:\[\e[1;34m\]\u`r=$?; test $r -ne 0 && echo " \[\e[1;31m\]ret:$r"`\[
\e[m\]$ '
And this code will print an ugly little ASCII Table
#!/bin/sh
############################################################
# Print the ASCII Color Table
############################################################
for i in 0 1 4 5 7 ; do
echo "----------------------------------------------------------------"
printf "ESC[%s;Foreground;Background - \n" $i
for fore in 30 31 32 33 34 35 36 37; do
for back in 40 41 42 43 44 45 46 47; do
printf '\033[%s;%s;%sm %02s;%02s ' $i $fore $back $fore $back
done
printf '\n'
done
printf '\033[0m'
done
catfish
02-08-2005, 01:32 AM
Hey AntiGenX,
That is a very nice script. Is it under public domain/commons?
I cleaned it up a little and would like to add it to my bag of tricks for testing terminal capabilities.
#!/bin/sh
############################################################
# Print the ASCII Color Table
############################################################
# originally by AntiGenX
# from: http://forums.macosxhints.com/showthread.php?t=17068
#
# edits and cleanup by catfish
#
for i in 0 1 4 5 7; do
case $i in
0) MODE="Normal";;
1) MODE="Bold";;
4) MODE="Underline";;
5) MODE="Blink";;
7) MODE="Inverse";;
*) MODE="undefined";;
esac
echo
echo "----------------------------------------------------------------"
printf " Mode: %-12s Code: ESC[%s;Foreground;Background\n" ${MODE} $i
echo "----------------------------------------------------------------"
for fore in 30 31 32 33 34 35 36 37; do
for back in 40 41 42 43 44 45 46 47; do
printf '\033[%s;%s;%sm %02s;%02s ' $i $fore $back $fore $back
done
printf '\033[0m'
echo
done
done
echo
exit 0
AntiGenX
02-08-2005, 10:09 AM
It's just a shell script so I really never thought about a license... Do with it what you will.
catfish
02-11-2005, 03:42 PM
Do with it what you will.
cool
-----------
Santiago, try export COLUMNS and see if that fixes it.
Gnarlodious
02-19-2005, 10:17 PM
PS1='\[\e[0;36m\]\h:\[\e[1;37m\]\w:\[\e[1;34m\]\u`r=$?; test $r -ne 0 && echo " \[\e[1;31m\]ret:$r"`\[
\e[m\]$ '
AntiGenX, I'm using a prompt based on this and I like it :)
But it has a problem when I scroll up the history, wrapped lines move upward in the window and make it impossible to edit the command.
Maybe it's the same problem Santiago was having, I don't know. Do you know a solution?
-- Gnarlie's Applescript page:
http://Gnarlodious.com/Apple/AppleScript/
SpeedFrog
02-22-2005, 03:51 AM
Another thing you might want to try is adding "shopt -s checkwinsize" to your .bashrc - this will force Bash to check your terminal's row/column sizes after each command, before your prompt is displayed.
Cezary Okupski
10-26-2007, 12:45 PM
I had the same issue, and I don't think the problem has to do with the TERM variable. In fact, I tried changing it to "ansi" myself, and emacs got all screwed up.
You didn't put the value of PS1 in your original post, so I can only assume you're having the same issues I was, which was failing to mark the ANSI escape sequences as non-printing characters.
Before I had the following value for PS1:
'\e[0;34m\h:\w [\!]\$\e[0m '
which gave me a nice blue prompt of the following form
hostname:working-directory [command-number]$
However, I had the same line-wrapping problem you did. The fix was to insert \[ and \] around the ANSI escapes so that the shell knows not to include them in the line wrapping calculation. This results in the following value for PS1:
'\[\e[0;34m\]\h:\w [\!]\$\[\e[m\] '
Many thanks for this input. That worked for me. I've been bearing it for two years so I'm happy to find this solution. There must be a misleading tutorial somewhere online about colour prompts. I would also add that this \e is sometimes referred to as \033, but I guess everyone would figure it out.
vBulletin® v3.8.7, Copyright ©2000-2013, vBulletin Solutions, Inc.