6

I am working with control sequences for text formatting and have stumbled upon some unexpected behavior. I have some text to output, in the middle of this text there is some smaller text block highlighted with a colored background. The original text may be pretty long, it may take a few lines, so the colored text block in the middle may appear on the multiple lines - starts on the one line and finishes on the other. Everything seems to work fine until it reaches the bottom of the terminal window, a lot of whitespace becomes colored:

enter image description here

Here is a script to reproduce:

# color.sh
echo -e 'default \x1B[43m color \n color \x1B[49m default';

As you can see, I've added a newline character \n in the text block, just to reproduce, but it my situation, when a text is pretty long and it does not fit into a single line, colored block gets split into multiple line, and as a result I have the same colored whitespace after the text.

# color-long.sh
echo -e 'default default default default default default default default default \x1B[43m color color \x1B[49m default';

enter image description here

I get this on Ubuntu 14.04, but was able to reproduce the same behavior on Yosemite 10.10.

I wonder what is the reason of this behavior and how it can be fixed without using different utilities for output (instead of echo), but maybe by using the same control sequences. I have control over the text, but not over the output process.

I've already tried to wrap sequences like \[\x1B[43m\], \001\x1B[43m\002, but it does not give any result, just adds extra [] to the text or outputs some unrecognized symbols.

3

This has nothing to do with bash, it is purely an effect of the terminal's behavior, specifically scroll. When you reach the bottom of the screen, and start to type on the next line, the terminal creates a new blank line by pushing everything up one line. (In older terminals this destroys the top line. In newer terminals the top line is just pushed into the scrollback buffer.) Now here is the hard question, what color is the new line. The foreground color is not an issue, because you cannot see it, but the background color . . . (In the days they started arguing it could be black gray or white (or actually black green, bright green or the same in amber)) There were experiments to just use black, but there were complaints. What was settled on is that the new line (or cleared area in a clear up the whole screen in the case of a screen clear) would have the current background color as the background color of the affected area. So this behavior is by design, because it does the right thing in most cases.

So what do you want to do to get the behavior you want? When you change back to black background (or at the end of the line) send a clear to end of line which will set the background color for the rest of the line.

  • echo -e 'default \x1B[43m color \n color \x1B[49m\x1B[K default' – hildred Jun 29 '15 at 19:58
  • Yes, clearing works great for my case, even when there are multiple colors in the line. Thank you for a complete explanation of the problem's origin. – Michael Radionov Jun 29 '15 at 20:12
  • "because it does the right thing in most cases" – this is strongly debatable, in fact, I think it's outright the opposite. See the VTE bugreport linked by Thomas Dickey. – egmont Dec 11 '15 at 7:58
  • Unfortunately, clearing to the end of the line causes an even more severe issue in many emulators: if your text happens to end at the right end of the terminal, the cursor is set back by one position and hence one character from your output will be overridden. E.g. follow the Grep bugreport link from the aforementioned VTE bug. – egmont Dec 11 '15 at 7:59
5

Agreeing with @hildred that this is terminal-specific behavior, there are some points of disagreement:

  • if an application happens to be switched to the alternate screen (as in a full-screen program running in xterm, with a suitable terminal description), no text is shifted into the scrollback buffer.
  • there is no "right" or "wrong" behavior, but only conventions.
  • there are several related features in the terminal design which (could be) independent.
  • due to convention (and a few examples such as the Linux console, xterm and — a little different — rxvt), many color terminals behave similarly.
  • The ncurses FAQ My terminal shows some uncolored spaces goes into more detail.

Convention is a strong argument; programs rely upon these design choices not changing. For a few examples where that leads to problems, consider a few cases:

A recent bug report for VTE, #754596 provides entertaining reading. It seems that VTE's developers suggested just changing the behavior to see what happens:

For starter, we could just "fix" our code (remove the "Match xterm and fill the new row when scrolling" 6 lines from _vte_terminal_cursor_down()) for the next development cycle and see if anyone complains about something breaking. Then we'll have a better understanding of the situation.

  • 2
    this guy knows what hes talking about – mikeserv Oct 20 '15 at 13:06
  • 1
    @mikeserv, this guy is the maintainer of ncurses and xterm. – Stéphane Chazelas Oct 22 '15 at 8:53
  • @StéphaneChazelas - yes. I know. – mikeserv Oct 22 '15 at 15:00
  • 1. alternate screen behavior is enough different than normal behavior to be an entirely different discussion, and off topic as not applicable to the question at hand, 2. it is also a convention to precede each byte of character data with a byte of color data, but it is the wrong convention for a terminal emulator. 3 agreed that it is possible not that anyone thinks it would be a good idea. 4. this behavior predates color. 5. good read. Further the behavior VTE suggests is undoubtedly appealing, but I wouldn't want to be responsible for designing it using ttl logic when this debate began. – hildred Dec 16 '15 at 2:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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