diff --git a/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php b/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php index 3f3f1434be46c..3d499bbcc9e37 100644 --- a/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php +++ b/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php @@ -48,9 +48,9 @@ public function __construct($stream, array &$sections, int $verbosity, bool $dec public function setMaxHeight(int $maxHeight): void { // when changing max height, clear output of current section and redraw again with the new height - $existingContent = $this->popStreamContentUntilCurrentSection($this->maxHeight ? min($this->maxHeight, $this->lines) : $this->lines); - + $previousMaxHeight = $this->maxHeight; $this->maxHeight = $maxHeight; + $existingContent = $this->popStreamContentUntilCurrentSection($previousMaxHeight ? min($previousMaxHeight, $this->lines) : $this->lines); parent::doWrite($this->getVisibleContent(), false); parent::doWrite($existingContent, false); @@ -213,7 +213,7 @@ private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFr break; } - $numberOfLinesToClear += $section->lines; + $numberOfLinesToClear += $section->maxHeight ? min($section->lines, $section->maxHeight) : $section->lines; if ('' !== $sectionContent = $section->getVisibleContent()) { if (!str_ends_with($sectionContent, \PHP_EOL)) { $sectionContent .= \PHP_EOL; diff --git a/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php b/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php index 984ade26608a7..0a775fd68e4f9 100644 --- a/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php +++ b/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php @@ -133,6 +133,40 @@ public function testMaxHeight() $this->assertEquals($expected, stream_get_contents($output->getStream())); } + public function testMaxHeightMultipleSections() + { + $expected = ''; + $sections = []; + + $firstSection = new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter()); + $firstSection->setMaxHeight(3); + + $secondSection = new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter()); + $secondSection->setMaxHeight(3); + + // fill the first section + $firstSection->writeln(['One', 'Two', 'Three']); + $expected .= 'One'.\PHP_EOL.'Two'.\PHP_EOL.'Three'.\PHP_EOL; + + // fill the second section + $secondSection->writeln(['One', 'Two', 'Three']); + $expected .= 'One'.\PHP_EOL.'Two'.\PHP_EOL.'Three'.\PHP_EOL; + + // cause overflow of second section (redraw whole section, without first line) + $secondSection->writeln('Four'); + $expected .= "\x1b[3A\x1b[0J"; + $expected .= 'Two'.\PHP_EOL.'Three'.\PHP_EOL.'Four'.\PHP_EOL; + + // cause overflow of first section (redraw whole section, without first line) + $firstSection->writeln("Four\nFive\nSix"); + $expected .= "\x1b[6A\x1b[0J"; + $expected .= 'Four'.\PHP_EOL.'Five'.\PHP_EOL.'Six'.\PHP_EOL; + $expected .= 'Two'.\PHP_EOL.'Three'.\PHP_EOL.'Four'.\PHP_EOL; + + rewind($this->stream); + $this->assertEquals(escapeshellcmd($expected), escapeshellcmd(stream_get_contents($this->stream))); + } + public function testMaxHeightWithoutNewLine() { $expected = '';