From 08e0143c16cdb178ccf55fda9d167e53b5ef0b43 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Thu, 5 Mar 2015 21:19:42 +0100 Subject: [PATCH] created Console::wrapText() to imrove console help output on small screens --- framework/CHANGELOG.md | 2 + .../console/controllers/HelpController.php | 18 +++++++-- framework/helpers/BaseConsole.php | 40 +++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 129f2d4210..24d44fabd6 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -7,6 +7,8 @@ Yii Framework 2 Change Log - Bug #7529: Fixed `yii\web\Response::sendContentAsFile()` that was broken in 2.0.3 (samdark) - Enh #7488: Added `StringHelper::explode` to perform explode with trimming and skipping of empty elements (SilverFire, nineinchnick, creocoder, samdark) - Enh #7562: `yii help` now lists all sub-commands by default (callmez) +- Enh: Added `yii\helper\Console::wrapText()` method to wrap indented text by console window width and used it in `yii help` command (cebe) + 2.0.3 March 01, 2015 -------------------- diff --git a/framework/console/controllers/HelpController.php b/framework/console/controllers/HelpController.php index e26d69b7ce..977a5969a1 100644 --- a/framework/console/controllers/HelpController.php +++ b/framework/console/controllers/HelpController.php @@ -210,7 +210,8 @@ class HelpController extends Controller } foreach ($commands as $command => $description) { $this->stdout('- ' . $this->ansiFormat($command, Console::FG_YELLOW)); - $this->stdout(str_repeat(' ', $len + 5 - strlen($command)) . $description); + $this->stdout(str_repeat(' ', $len + 4 - strlen($command))); + $this->stdout(Console::wrapText($description, $len + 4 + 2), Console::BOLD); $this->stdout("\n"); $result = Yii::$app->createController($command); @@ -228,7 +229,8 @@ class HelpController extends Controller } $summary = $controller->getActionHelpSummary($controller->createAction($action)); if ($summary !== '') { - $this->stdout(str_repeat(' ', $len + 5 - strlen($string)) . $summary); + $this->stdout(str_repeat(' ', $len + 4 - strlen($string))); + $this->stdout(Console::wrapText($summary, $len + 4 + 2)); } $this->stdout("\n"); } @@ -263,14 +265,24 @@ class HelpController extends Controller if (!empty($actions)) { $this->stdout("\nSUB-COMMANDS\n\n", Console::BOLD); $prefix = $controller->getUniqueId(); + + $maxlen = 5; + foreach ($actions as $action) { + $len = strlen($prefix.'/'.$action) + 2 + ($action === $controller->defaultAction ? 10 : 0); + if ($maxlen < $len) { + $maxlen = $len; + } + } foreach ($actions as $action) { $this->stdout('- ' . $this->ansiFormat($prefix.'/'.$action, Console::FG_YELLOW)); + $len = strlen($prefix.'/'.$action) + 2; if ($action === $controller->defaultAction) { $this->stdout(' (default)', Console::FG_GREEN); + $len += 10; } $summary = $controller->getActionHelpSummary($controller->createAction($action)); if ($summary !== '') { - $this->stdout(': ' . $summary); + $this->stdout(str_repeat(' ', $maxlen - $len + 2) . Console::wrapText($summary, $maxlen + 2)); } $this->stdout("\n"); } diff --git a/framework/helpers/BaseConsole.php b/framework/helpers/BaseConsole.php index 366cee18a9..b12e852902 100644 --- a/framework/helpers/BaseConsole.php +++ b/framework/helpers/BaseConsole.php @@ -635,6 +635,46 @@ class BaseConsole return $size = false; } + /** + * Word wrap text with indentation to fit the screen size + * + * If screen size could not be detected, or the indentation is greater than the screen size, the text will not be wrapped. + * + * The first line will **not** be indented, so `Console::wrapText("Lorem ipsum dolor sit amet.", 4)` will result in the + * following output, given the screen width is 16 characters: + * + * ``` + * Lorem ipsum + * dolor sit + * amet. + * ``` + * + * @param string $text the text to be wrapped + * @param integer $indent number of spaces to use for indentation. + * @param boolean $refresh whether to force refresh of screen size. + * This will be passed to [[getScreenSize()]]. + * @return string the wrapped text. + * @since 2.0.3 + */ + public static function wrapText($text, $indent = 0, $refresh = false) + { + $size = static::getScreenSize($refresh); + if ($size === false || $size[0] <= $indent) { + return $text; + } + $pad = str_repeat(' ', $indent); + $lines = explode("\n", wordwrap($text, $size[0] - $indent, "\n", true)); + $first = true; + foreach($lines as $i => $line) { + if ($first) { + $first = false; + continue; + } + $lines[$i] = $pad . $line; + } + return implode("\n", $lines); + } + /** * Gets input from STDIN and returns a string right-trimmed for EOLs. *