annotate vendor/symfony/console/Helper/ProgressBar.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\Console\Helper;
Chris@0 13
Chris@17 14 use Symfony\Component\Console\Exception\LogicException;
Chris@0 15 use Symfony\Component\Console\Output\ConsoleOutputInterface;
Chris@0 16 use Symfony\Component\Console\Output\OutputInterface;
Chris@0 17 use Symfony\Component\Console\Terminal;
Chris@0 18
Chris@0 19 /**
Chris@0 20 * The ProgressBar provides helpers to display progress output.
Chris@0 21 *
Chris@0 22 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 23 * @author Chris Jones <leeked@gmail.com>
Chris@0 24 */
Chris@14 25 final class ProgressBar
Chris@0 26 {
Chris@0 27 private $barWidth = 28;
Chris@0 28 private $barChar;
Chris@0 29 private $emptyBarChar = '-';
Chris@0 30 private $progressChar = '>';
Chris@0 31 private $format;
Chris@0 32 private $internalFormat;
Chris@0 33 private $redrawFreq = 1;
Chris@0 34 private $output;
Chris@0 35 private $step = 0;
Chris@0 36 private $max;
Chris@0 37 private $startTime;
Chris@0 38 private $stepWidth;
Chris@0 39 private $percent = 0.0;
Chris@0 40 private $formatLineCount;
Chris@17 41 private $messages = [];
Chris@0 42 private $overwrite = true;
Chris@0 43 private $terminal;
Chris@0 44 private $firstRun = true;
Chris@0 45
Chris@0 46 private static $formatters;
Chris@0 47 private static $formats;
Chris@0 48
Chris@0 49 /**
Chris@0 50 * @param OutputInterface $output An OutputInterface instance
Chris@0 51 * @param int $max Maximum steps (0 if unknown)
Chris@0 52 */
Chris@0 53 public function __construct(OutputInterface $output, $max = 0)
Chris@0 54 {
Chris@0 55 if ($output instanceof ConsoleOutputInterface) {
Chris@0 56 $output = $output->getErrorOutput();
Chris@0 57 }
Chris@0 58
Chris@0 59 $this->output = $output;
Chris@0 60 $this->setMaxSteps($max);
Chris@0 61 $this->terminal = new Terminal();
Chris@0 62
Chris@0 63 if (!$this->output->isDecorated()) {
Chris@0 64 // disable overwrite when output does not support ANSI codes.
Chris@0 65 $this->overwrite = false;
Chris@0 66
Chris@0 67 // set a reasonable redraw frequency so output isn't flooded
Chris@0 68 $this->setRedrawFrequency($max / 10);
Chris@0 69 }
Chris@0 70
Chris@0 71 $this->startTime = time();
Chris@0 72 }
Chris@0 73
Chris@0 74 /**
Chris@0 75 * Sets a placeholder formatter for a given name.
Chris@0 76 *
Chris@0 77 * This method also allow you to override an existing placeholder.
Chris@0 78 *
Chris@0 79 * @param string $name The placeholder name (including the delimiter char like %)
Chris@0 80 * @param callable $callable A PHP callable
Chris@0 81 */
Chris@0 82 public static function setPlaceholderFormatterDefinition($name, callable $callable)
Chris@0 83 {
Chris@0 84 if (!self::$formatters) {
Chris@0 85 self::$formatters = self::initPlaceholderFormatters();
Chris@0 86 }
Chris@0 87
Chris@0 88 self::$formatters[$name] = $callable;
Chris@0 89 }
Chris@0 90
Chris@0 91 /**
Chris@0 92 * Gets the placeholder formatter for a given name.
Chris@0 93 *
Chris@0 94 * @param string $name The placeholder name (including the delimiter char like %)
Chris@0 95 *
Chris@0 96 * @return callable|null A PHP callable
Chris@0 97 */
Chris@0 98 public static function getPlaceholderFormatterDefinition($name)
Chris@0 99 {
Chris@0 100 if (!self::$formatters) {
Chris@0 101 self::$formatters = self::initPlaceholderFormatters();
Chris@0 102 }
Chris@0 103
Chris@0 104 return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
Chris@0 105 }
Chris@0 106
Chris@0 107 /**
Chris@0 108 * Sets a format for a given name.
Chris@0 109 *
Chris@0 110 * This method also allow you to override an existing format.
Chris@0 111 *
Chris@0 112 * @param string $name The format name
Chris@0 113 * @param string $format A format string
Chris@0 114 */
Chris@0 115 public static function setFormatDefinition($name, $format)
Chris@0 116 {
Chris@0 117 if (!self::$formats) {
Chris@0 118 self::$formats = self::initFormats();
Chris@0 119 }
Chris@0 120
Chris@0 121 self::$formats[$name] = $format;
Chris@0 122 }
Chris@0 123
Chris@0 124 /**
Chris@0 125 * Gets the format for a given name.
Chris@0 126 *
Chris@0 127 * @param string $name The format name
Chris@0 128 *
Chris@0 129 * @return string|null A format string
Chris@0 130 */
Chris@0 131 public static function getFormatDefinition($name)
Chris@0 132 {
Chris@0 133 if (!self::$formats) {
Chris@0 134 self::$formats = self::initFormats();
Chris@0 135 }
Chris@0 136
Chris@0 137 return isset(self::$formats[$name]) ? self::$formats[$name] : null;
Chris@0 138 }
Chris@0 139
Chris@0 140 /**
Chris@0 141 * Associates a text with a named placeholder.
Chris@0 142 *
Chris@0 143 * The text is displayed when the progress bar is rendered but only
Chris@0 144 * when the corresponding placeholder is part of the custom format line
Chris@0 145 * (by wrapping the name with %).
Chris@0 146 *
Chris@0 147 * @param string $message The text to associate with the placeholder
Chris@0 148 * @param string $name The name of the placeholder
Chris@0 149 */
Chris@0 150 public function setMessage($message, $name = 'message')
Chris@0 151 {
Chris@0 152 $this->messages[$name] = $message;
Chris@0 153 }
Chris@0 154
Chris@0 155 public function getMessage($name = 'message')
Chris@0 156 {
Chris@0 157 return $this->messages[$name];
Chris@0 158 }
Chris@0 159
Chris@0 160 /**
Chris@0 161 * Gets the progress bar start time.
Chris@0 162 *
Chris@0 163 * @return int The progress bar start time
Chris@0 164 */
Chris@0 165 public function getStartTime()
Chris@0 166 {
Chris@0 167 return $this->startTime;
Chris@0 168 }
Chris@0 169
Chris@0 170 /**
Chris@0 171 * Gets the progress bar maximal steps.
Chris@0 172 *
Chris@0 173 * @return int The progress bar max steps
Chris@0 174 */
Chris@0 175 public function getMaxSteps()
Chris@0 176 {
Chris@0 177 return $this->max;
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * Gets the current step position.
Chris@0 182 *
Chris@0 183 * @return int The progress bar step
Chris@0 184 */
Chris@0 185 public function getProgress()
Chris@0 186 {
Chris@0 187 return $this->step;
Chris@0 188 }
Chris@0 189
Chris@0 190 /**
Chris@0 191 * Gets the progress bar step width.
Chris@0 192 *
Chris@0 193 * @return int The progress bar step width
Chris@0 194 */
Chris@0 195 private function getStepWidth()
Chris@0 196 {
Chris@0 197 return $this->stepWidth;
Chris@0 198 }
Chris@0 199
Chris@0 200 /**
Chris@0 201 * Gets the current progress bar percent.
Chris@0 202 *
Chris@0 203 * @return float The current progress bar percent
Chris@0 204 */
Chris@0 205 public function getProgressPercent()
Chris@0 206 {
Chris@0 207 return $this->percent;
Chris@0 208 }
Chris@0 209
Chris@0 210 /**
Chris@0 211 * Sets the progress bar width.
Chris@0 212 *
Chris@0 213 * @param int $size The progress bar size
Chris@0 214 */
Chris@0 215 public function setBarWidth($size)
Chris@0 216 {
Chris@0 217 $this->barWidth = max(1, (int) $size);
Chris@0 218 }
Chris@0 219
Chris@0 220 /**
Chris@0 221 * Gets the progress bar width.
Chris@0 222 *
Chris@0 223 * @return int The progress bar size
Chris@0 224 */
Chris@0 225 public function getBarWidth()
Chris@0 226 {
Chris@0 227 return $this->barWidth;
Chris@0 228 }
Chris@0 229
Chris@0 230 /**
Chris@0 231 * Sets the bar character.
Chris@0 232 *
Chris@0 233 * @param string $char A character
Chris@0 234 */
Chris@0 235 public function setBarCharacter($char)
Chris@0 236 {
Chris@0 237 $this->barChar = $char;
Chris@0 238 }
Chris@0 239
Chris@0 240 /**
Chris@0 241 * Gets the bar character.
Chris@0 242 *
Chris@0 243 * @return string A character
Chris@0 244 */
Chris@0 245 public function getBarCharacter()
Chris@0 246 {
Chris@0 247 if (null === $this->barChar) {
Chris@0 248 return $this->max ? '=' : $this->emptyBarChar;
Chris@0 249 }
Chris@0 250
Chris@0 251 return $this->barChar;
Chris@0 252 }
Chris@0 253
Chris@0 254 /**
Chris@0 255 * Sets the empty bar character.
Chris@0 256 *
Chris@0 257 * @param string $char A character
Chris@0 258 */
Chris@0 259 public function setEmptyBarCharacter($char)
Chris@0 260 {
Chris@0 261 $this->emptyBarChar = $char;
Chris@0 262 }
Chris@0 263
Chris@0 264 /**
Chris@0 265 * Gets the empty bar character.
Chris@0 266 *
Chris@0 267 * @return string A character
Chris@0 268 */
Chris@0 269 public function getEmptyBarCharacter()
Chris@0 270 {
Chris@0 271 return $this->emptyBarChar;
Chris@0 272 }
Chris@0 273
Chris@0 274 /**
Chris@0 275 * Sets the progress bar character.
Chris@0 276 *
Chris@0 277 * @param string $char A character
Chris@0 278 */
Chris@0 279 public function setProgressCharacter($char)
Chris@0 280 {
Chris@0 281 $this->progressChar = $char;
Chris@0 282 }
Chris@0 283
Chris@0 284 /**
Chris@0 285 * Gets the progress bar character.
Chris@0 286 *
Chris@0 287 * @return string A character
Chris@0 288 */
Chris@0 289 public function getProgressCharacter()
Chris@0 290 {
Chris@0 291 return $this->progressChar;
Chris@0 292 }
Chris@0 293
Chris@0 294 /**
Chris@0 295 * Sets the progress bar format.
Chris@0 296 *
Chris@0 297 * @param string $format The format
Chris@0 298 */
Chris@0 299 public function setFormat($format)
Chris@0 300 {
Chris@0 301 $this->format = null;
Chris@0 302 $this->internalFormat = $format;
Chris@0 303 }
Chris@0 304
Chris@0 305 /**
Chris@0 306 * Sets the redraw frequency.
Chris@0 307 *
Chris@0 308 * @param int|float $freq The frequency in steps
Chris@0 309 */
Chris@0 310 public function setRedrawFrequency($freq)
Chris@0 311 {
Chris@0 312 $this->redrawFreq = max((int) $freq, 1);
Chris@0 313 }
Chris@0 314
Chris@0 315 /**
Chris@0 316 * Starts the progress output.
Chris@0 317 *
Chris@0 318 * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
Chris@0 319 */
Chris@0 320 public function start($max = null)
Chris@0 321 {
Chris@0 322 $this->startTime = time();
Chris@0 323 $this->step = 0;
Chris@0 324 $this->percent = 0.0;
Chris@0 325
Chris@0 326 if (null !== $max) {
Chris@0 327 $this->setMaxSteps($max);
Chris@0 328 }
Chris@0 329
Chris@0 330 $this->display();
Chris@0 331 }
Chris@0 332
Chris@0 333 /**
Chris@0 334 * Advances the progress output X steps.
Chris@0 335 *
Chris@0 336 * @param int $step Number of steps to advance
Chris@0 337 */
Chris@0 338 public function advance($step = 1)
Chris@0 339 {
Chris@0 340 $this->setProgress($this->step + $step);
Chris@0 341 }
Chris@0 342
Chris@0 343 /**
Chris@0 344 * Sets whether to overwrite the progressbar, false for new line.
Chris@0 345 *
Chris@0 346 * @param bool $overwrite
Chris@0 347 */
Chris@0 348 public function setOverwrite($overwrite)
Chris@0 349 {
Chris@0 350 $this->overwrite = (bool) $overwrite;
Chris@0 351 }
Chris@0 352
Chris@0 353 /**
Chris@0 354 * Sets the current progress.
Chris@0 355 *
Chris@0 356 * @param int $step The current progress
Chris@0 357 */
Chris@0 358 public function setProgress($step)
Chris@0 359 {
Chris@0 360 $step = (int) $step;
Chris@0 361
Chris@0 362 if ($this->max && $step > $this->max) {
Chris@0 363 $this->max = $step;
Chris@0 364 } elseif ($step < 0) {
Chris@0 365 $step = 0;
Chris@0 366 }
Chris@0 367
Chris@0 368 $prevPeriod = (int) ($this->step / $this->redrawFreq);
Chris@0 369 $currPeriod = (int) ($step / $this->redrawFreq);
Chris@0 370 $this->step = $step;
Chris@0 371 $this->percent = $this->max ? (float) $this->step / $this->max : 0;
Chris@0 372 if ($prevPeriod !== $currPeriod || $this->max === $step) {
Chris@0 373 $this->display();
Chris@0 374 }
Chris@0 375 }
Chris@0 376
Chris@0 377 /**
Chris@0 378 * Finishes the progress output.
Chris@0 379 */
Chris@0 380 public function finish()
Chris@0 381 {
Chris@0 382 if (!$this->max) {
Chris@0 383 $this->max = $this->step;
Chris@0 384 }
Chris@0 385
Chris@0 386 if ($this->step === $this->max && !$this->overwrite) {
Chris@0 387 // prevent double 100% output
Chris@0 388 return;
Chris@0 389 }
Chris@0 390
Chris@0 391 $this->setProgress($this->max);
Chris@0 392 }
Chris@0 393
Chris@0 394 /**
Chris@0 395 * Outputs the current progress string.
Chris@0 396 */
Chris@0 397 public function display()
Chris@0 398 {
Chris@0 399 if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
Chris@0 400 return;
Chris@0 401 }
Chris@0 402
Chris@0 403 if (null === $this->format) {
Chris@0 404 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
Chris@0 405 }
Chris@0 406
Chris@0 407 $this->overwrite($this->buildLine());
Chris@0 408 }
Chris@0 409
Chris@0 410 /**
Chris@0 411 * Removes the progress bar from the current line.
Chris@0 412 *
Chris@0 413 * This is useful if you wish to write some output
Chris@0 414 * while a progress bar is running.
Chris@0 415 * Call display() to show the progress bar again.
Chris@0 416 */
Chris@0 417 public function clear()
Chris@0 418 {
Chris@0 419 if (!$this->overwrite) {
Chris@0 420 return;
Chris@0 421 }
Chris@0 422
Chris@0 423 if (null === $this->format) {
Chris@0 424 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
Chris@0 425 }
Chris@0 426
Chris@0 427 $this->overwrite('');
Chris@0 428 }
Chris@0 429
Chris@0 430 /**
Chris@0 431 * Sets the progress bar format.
Chris@0 432 *
Chris@0 433 * @param string $format The format
Chris@0 434 */
Chris@0 435 private function setRealFormat($format)
Chris@0 436 {
Chris@0 437 // try to use the _nomax variant if available
Chris@0 438 if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
Chris@0 439 $this->format = self::getFormatDefinition($format.'_nomax');
Chris@0 440 } elseif (null !== self::getFormatDefinition($format)) {
Chris@0 441 $this->format = self::getFormatDefinition($format);
Chris@0 442 } else {
Chris@0 443 $this->format = $format;
Chris@0 444 }
Chris@0 445
Chris@0 446 $this->formatLineCount = substr_count($this->format, "\n");
Chris@0 447 }
Chris@0 448
Chris@0 449 /**
Chris@0 450 * Sets the progress bar maximal steps.
Chris@0 451 *
Chris@0 452 * @param int $max The progress bar max steps
Chris@0 453 */
Chris@0 454 private function setMaxSteps($max)
Chris@0 455 {
Chris@0 456 $this->max = max(0, (int) $max);
Chris@0 457 $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
Chris@0 458 }
Chris@0 459
Chris@0 460 /**
Chris@0 461 * Overwrites a previous message to the output.
Chris@0 462 *
Chris@0 463 * @param string $message The message
Chris@0 464 */
Chris@0 465 private function overwrite($message)
Chris@0 466 {
Chris@0 467 if ($this->overwrite) {
Chris@0 468 if (!$this->firstRun) {
Chris@0 469 // Erase previous lines
Chris@0 470 if ($this->formatLineCount > 0) {
Chris@18 471 $message = str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount).$message;
Chris@0 472 }
Chris@18 473
Chris@18 474 // Move the cursor to the beginning of the line and erase the line
Chris@18 475 $message = "\x0D\x1B[2K$message";
Chris@0 476 }
Chris@0 477 } elseif ($this->step > 0) {
Chris@18 478 $message = PHP_EOL.$message;
Chris@0 479 }
Chris@0 480
Chris@0 481 $this->firstRun = false;
Chris@0 482
Chris@0 483 $this->output->write($message);
Chris@0 484 }
Chris@0 485
Chris@0 486 private function determineBestFormat()
Chris@0 487 {
Chris@0 488 switch ($this->output->getVerbosity()) {
Chris@0 489 // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
Chris@0 490 case OutputInterface::VERBOSITY_VERBOSE:
Chris@0 491 return $this->max ? 'verbose' : 'verbose_nomax';
Chris@0 492 case OutputInterface::VERBOSITY_VERY_VERBOSE:
Chris@0 493 return $this->max ? 'very_verbose' : 'very_verbose_nomax';
Chris@0 494 case OutputInterface::VERBOSITY_DEBUG:
Chris@0 495 return $this->max ? 'debug' : 'debug_nomax';
Chris@0 496 default:
Chris@0 497 return $this->max ? 'normal' : 'normal_nomax';
Chris@0 498 }
Chris@0 499 }
Chris@0 500
Chris@0 501 private static function initPlaceholderFormatters()
Chris@0 502 {
Chris@17 503 return [
Chris@17 504 'bar' => function (self $bar, OutputInterface $output) {
Chris@0 505 $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
Chris@0 506 $display = str_repeat($bar->getBarCharacter(), $completeBars);
Chris@0 507 if ($completeBars < $bar->getBarWidth()) {
Chris@0 508 $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
Chris@0 509 $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
Chris@0 510 }
Chris@0 511
Chris@0 512 return $display;
Chris@0 513 },
Chris@17 514 'elapsed' => function (self $bar) {
Chris@0 515 return Helper::formatTime(time() - $bar->getStartTime());
Chris@0 516 },
Chris@17 517 'remaining' => function (self $bar) {
Chris@0 518 if (!$bar->getMaxSteps()) {
Chris@0 519 throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
Chris@0 520 }
Chris@0 521
Chris@0 522 if (!$bar->getProgress()) {
Chris@0 523 $remaining = 0;
Chris@0 524 } else {
Chris@0 525 $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
Chris@0 526 }
Chris@0 527
Chris@0 528 return Helper::formatTime($remaining);
Chris@0 529 },
Chris@17 530 'estimated' => function (self $bar) {
Chris@0 531 if (!$bar->getMaxSteps()) {
Chris@0 532 throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
Chris@0 533 }
Chris@0 534
Chris@0 535 if (!$bar->getProgress()) {
Chris@0 536 $estimated = 0;
Chris@0 537 } else {
Chris@0 538 $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
Chris@0 539 }
Chris@0 540
Chris@0 541 return Helper::formatTime($estimated);
Chris@0 542 },
Chris@17 543 'memory' => function (self $bar) {
Chris@0 544 return Helper::formatMemory(memory_get_usage(true));
Chris@0 545 },
Chris@17 546 'current' => function (self $bar) {
Chris@0 547 return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
Chris@0 548 },
Chris@17 549 'max' => function (self $bar) {
Chris@0 550 return $bar->getMaxSteps();
Chris@0 551 },
Chris@17 552 'percent' => function (self $bar) {
Chris@0 553 return floor($bar->getProgressPercent() * 100);
Chris@0 554 },
Chris@17 555 ];
Chris@0 556 }
Chris@0 557
Chris@0 558 private static function initFormats()
Chris@0 559 {
Chris@17 560 return [
Chris@0 561 'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
Chris@0 562 'normal_nomax' => ' %current% [%bar%]',
Chris@0 563
Chris@0 564 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
Chris@0 565 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
Chris@0 566
Chris@0 567 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
Chris@0 568 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
Chris@0 569
Chris@0 570 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
Chris@0 571 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
Chris@17 572 ];
Chris@0 573 }
Chris@0 574
Chris@0 575 /**
Chris@0 576 * @return string
Chris@0 577 */
Chris@0 578 private function buildLine()
Chris@0 579 {
Chris@0 580 $regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
Chris@0 581 $callback = function ($matches) {
Chris@0 582 if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
Chris@17 583 $text = \call_user_func($formatter, $this, $this->output);
Chris@0 584 } elseif (isset($this->messages[$matches[1]])) {
Chris@0 585 $text = $this->messages[$matches[1]];
Chris@0 586 } else {
Chris@0 587 return $matches[0];
Chris@0 588 }
Chris@0 589
Chris@0 590 if (isset($matches[2])) {
Chris@0 591 $text = sprintf('%'.$matches[2], $text);
Chris@0 592 }
Chris@0 593
Chris@0 594 return $text;
Chris@0 595 };
Chris@0 596 $line = preg_replace_callback($regex, $callback, $this->format);
Chris@0 597
Chris@0 598 // gets string length for each sub line with multiline format
Chris@0 599 $linesLength = array_map(function ($subLine) {
Chris@0 600 return Helper::strlenWithoutDecoration($this->output->getFormatter(), rtrim($subLine, "\r"));
Chris@0 601 }, explode("\n", $line));
Chris@0 602
Chris@0 603 $linesWidth = max($linesLength);
Chris@0 604
Chris@0 605 $terminalWidth = $this->terminal->getWidth();
Chris@0 606 if ($linesWidth <= $terminalWidth) {
Chris@0 607 return $line;
Chris@0 608 }
Chris@0 609
Chris@0 610 $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth);
Chris@0 611
Chris@0 612 return preg_replace_callback($regex, $callback, $this->format);
Chris@0 613 }
Chris@0 614 }