0

Consider the following code (written in PHP, but that's not important. Answers may use pure Bash). The goal is to fill a terminal line with characters for the entire width of the line.

Now, if you minimise the terminal width during execution, excess characters from the previous time have to be cleared out to avoid a mess.

However, then, the previously echoed line will have been split into multiple lines, and echoing \r will return the cursor to the last of those lines, rather than the first, leaving behind garbage.

Is there any simple cure to this? The only thing I can think of is echoing the ANSI code for "CURSOR UP" as many times as the line was broken (minus one).

#!/usr/bin/env php
<?php
// Make sure window is 80 characters wide when running script
echo "00000000001111111111222222222233333333334444444444555555555566666666667777777777";
sleep(3); // Narrow window here (to 40-50 characters or so)
echo "\033[2K"; // CLEAR LINE
echo "\033[A"; // CURSOR UP
echo "\033[2K"; // CLEAR LINE
echo "\r"; // GOTO BEGINNING OF LINE
echo "Now we're back were we begun (where 000... used to be)";

?>
0

Note that the "traditional" behavior of terminal emulators is to chop long lines when the window is made narrower, while some terminals rewrap their contents on resize. Your question is relevant for the latter kind only.

The "erase in display" escape sequence (command: tput ed, sequence: \e[J) clears everything from the cursor (inclusive) to the end of the display. This is probably the simplest choice.

Note however that after printing into the last column of a row, the cursor is still logically in that last column (even though some emulators hide it or display it elsewhere), so this escape sequence clears that character in this case. In order to make sure you don't wipe out the last character of your message, you should probably emit it while the cursor is still in the first column, before printing the new message.

  • See updated post. This code works, but I'm just wondering if doing CURSOR UP is required. (From your comment, the answer seems to be "Yes", since my terminal rewraps the content.) – forthrin Feb 26 at 8:32
  • Well, if you emit one cursor up, the code will work only with emulators that rewrap their contents, and only if the width was narrowed but not more than to the half of the previous. Of course you can do the math of how many ups are required based on the previous width, but it'll still only work with rewrapping emulators if you move the cursor back after the delay. – egmont Feb 26 at 12:11
  • So CURSOR UP is the only way with wrapping terminals? Is there any way you can detect if the terminal is wrapping or not? – forthrin Feb 26 at 16:02

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.