Skip to content

Commit

Permalink
bug #18496 [Console] use ANSI escape sequences in ProgressBar overwri…
Browse files Browse the repository at this point in the history
…te method (alekitto)

This PR was squashed before being merged into the 2.7 branch (closes #18496).

Discussion
----------

[Console] use ANSI escape sequences in ProgressBar overwrite method

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | maybe
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #16957
| License       | MIT
| Doc PR        |

Rewritten `overwrite` method in ProgressBar class to use ANSI escape sequences to erase lines.
This removes the need to store the last message length as it is not needed to fill the buffer with spaces anymore. As a plus it correctly resets the cursor position while clearing the output

If the output is not decorated the behavior has not been changed.
Could possibly cause a BC break if testing against the decorated emitted output as binary string

Commits
-------

b6cca4c [Console] use ANSI escape sequences in ProgressBar overwrite method
  • Loading branch information
fabpot committed Apr 14, 2016
2 parents 6467b24 + b6cca4c commit 6400b70
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 33 deletions.
38 changes: 11 additions & 27 deletions src/Symfony/Component/Console/Helper/ProgressBar.php
Expand Up @@ -40,7 +40,6 @@ class ProgressBar
private $startTime;
private $stepWidth;
private $percent = 0.0;
private $lastMessagesLength = 0;
private $formatLineCount;
private $messages;
private $overwrite = true;
Expand Down Expand Up @@ -472,7 +471,7 @@ public function clear()
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
}

$this->overwrite(str_repeat("\n", $this->formatLineCount));
$this->overwrite('');
}

/**
Expand Down Expand Up @@ -512,37 +511,22 @@ private function setMaxSteps($max)
*/
private function overwrite($message)
{
$lines = explode("\n", $message);

// append whitespace to match the line's length
if (null !== $this->lastMessagesLength) {
foreach ($lines as $i => $line) {
if ($this->lastMessagesLength > Helper::strlenWithoutDecoration($this->output->getFormatter(), $line)) {
$lines[$i] = str_pad($line, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
}
}
}

if ($this->overwrite) {
// move back to the beginning of the progress bar before redrawing it
// Move the cursor to the beginning of the line
$this->output->write("\x0D");
} elseif ($this->step > 0) {
// move to new line
$this->output->writeln('');
}

if ($this->formatLineCount) {
$this->output->write(sprintf("\033[%dA", $this->formatLineCount));
}
$this->output->write(implode("\n", $lines));
// Erase the line
$this->output->write("\x1B[2K");

$this->lastMessagesLength = 0;
foreach ($lines as $line) {
$len = Helper::strlenWithoutDecoration($this->output->getFormatter(), $line);
if ($len > $this->lastMessagesLength) {
$this->lastMessagesLength = $len;
// Erase previous lines
if ($this->formatLineCount > 0) {
$this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
}
} elseif ($this->step > 0) {
$this->output->writeln('');
}

$this->output->write($message);
}

private function determineBestFormat()
Expand Down
12 changes: 6 additions & 6 deletions src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
Expand Up @@ -233,7 +233,7 @@ public function testOverwriteWithShorterLine()
$this->generateOutput(' 0/50 [>---------------------------] 0%').
$this->generateOutput(' 0/50 [>---------------------------] 0%').
$this->generateOutput(' 1/50 [>---------------------------] 2%').
$this->generateOutput(' 2/50 [=>--------------------------] '),
$this->generateOutput(' 2/50 [=>--------------------------]'),
stream_get_contents($output->getStream())
);
}
Expand Down Expand Up @@ -356,7 +356,7 @@ public function testClear()
$this->assertEquals(
$this->generateOutput(' 0/50 [>---------------------------] 0%').
$this->generateOutput(' 25/50 [==============>-------------] 50%').
$this->generateOutput(' '),
$this->generateOutput(''),
stream_get_contents($output->getStream())
);
}
Expand Down Expand Up @@ -554,9 +554,9 @@ public function testMultilineFormat()
rewind($output->getStream());
$this->assertEquals(
$this->generateOutput(">---------------------------\nfoobar").
$this->generateOutput("=========>------------------\nfoobar ").
$this->generateOutput(" \n ").
$this->generateOutput("============================\nfoobar "),
$this->generateOutput("=========>------------------\nfoobar").
"\x0D\x1B[2K\x1B[1A\x1B[2K".
$this->generateOutput("============================\nfoobar"),
stream_get_contents($output->getStream())
);
}
Expand Down Expand Up @@ -665,6 +665,6 @@ protected function generateOutput($expected)
{
$count = substr_count($expected, "\n");

return "\x0D".($count ? sprintf("\033[%dA", $count) : '').$expected;
return "\x0D\x1B[2K".($count ? str_repeat("\x1B[1A\x1B[2K", $count) : '').$expected;
}
}

0 comments on commit 6400b70

Please sign in to comment.