/vendor/psy/psysh/src/Psy/Output/ShellOutput.php

https://gitlab.com/techniconline/kmc · PHP · 201 lines · 106 code · 28 blank · 67 comment · 13 complexity · d661920022e74d999934cb595f54d17b MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of Psy Shell
  4. *
  5. * (c) 2012-2014 Justin Hileman
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Psy\Output;
  11. use Symfony\Component\Console\Formatter\OutputFormatterStyle;
  12. use Symfony\Component\Console\Output\ConsoleOutput;
  13. /**
  14. * A ConsoleOutput subclass specifically for Psy Shell output.
  15. */
  16. class ShellOutput extends ConsoleOutput
  17. {
  18. const NUMBER_LINES = 128;
  19. private $paging = 0;
  20. private $pager;
  21. /**
  22. * Construct a ShellOutput instance.
  23. *
  24. * @param mixed $verbosity (default: self::VERBOSITY_NORMAL)
  25. * @param boolean $decorated (default: null)
  26. * @param OutputFormatterInterface $formatter (default: null)
  27. * @param null|string|OutputPager $pager (default: null)
  28. */
  29. public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null, $pager = null)
  30. {
  31. parent::__construct($verbosity, $decorated, $formatter);
  32. $this->initFormatters();
  33. if ($pager === null) {
  34. $this->pager = new PassthruPager($this);
  35. } elseif (is_string($pager)) {
  36. $this->pager = new ProcOutputPager($this, $pager);
  37. } elseif ($pager instanceof OutputPager) {
  38. $this->pager = $pager;
  39. } else {
  40. throw new \InvalidArgumentException('Unexpected pager parameter: ' . $pager);
  41. }
  42. }
  43. /**
  44. * Page multiple lines of output.
  45. *
  46. * The output pager is started
  47. *
  48. * If $messages is callable, it will be called, passing this output instance
  49. * for rendering. Otherwise, all passed $messages are paged to output.
  50. *
  51. * Upon completion, the output pager is flushed.
  52. *
  53. * @param string|array|Closure $messages A string, array of strings or a callback.
  54. * @param int $type (default: 0)
  55. */
  56. public function page($messages, $type = 0)
  57. {
  58. if (is_string($messages)) {
  59. $messages = (array)$messages;
  60. }
  61. if (!is_array($messages) && !is_callable($messages)) {
  62. throw new \InvalidArgumentException('Paged output requires a string, array or callback.');
  63. }
  64. $this->startPaging();
  65. if (is_callable($messages)) {
  66. $messages($this);
  67. } else {
  68. $this->write($messages, true, $type);
  69. }
  70. $this->stopPaging();
  71. }
  72. /**
  73. * Start sending output to the output pager.
  74. */
  75. public function startPaging()
  76. {
  77. $this->paging++;
  78. }
  79. /**
  80. * Stop paging output and flush the output pager.
  81. */
  82. public function stopPaging()
  83. {
  84. $this->paging--;
  85. $this->closePager();
  86. }
  87. /**
  88. * Writes a message to the output.
  89. *
  90. * Optionally, pass `$type | self::NUMBER_LINES` as the $type parameter to
  91. * number the lines of output.
  92. *
  93. * @throws \InvalidArgumentException When unknown output type is given
  94. *
  95. * @param string|array $messages The message as an array of lines or a single string
  96. * @param Boolean $newline Whether to add a newline or not
  97. * @param integer $type The type of output
  98. */
  99. public function write($messages, $newline = false, $type = 0)
  100. {
  101. if ($this->getVerbosity() === self::VERBOSITY_QUIET) {
  102. return;
  103. }
  104. $messages = (array)$messages;
  105. if ($type & self::NUMBER_LINES) {
  106. $pad = strlen((string)count($messages));
  107. $template = $this->isDecorated() ? "<aside>%{$pad}s</aside>: %s" : "%{$pad}s: %s";
  108. if ($type & self::OUTPUT_RAW) {
  109. $messages = array_map(array('Symfony\Component\Console\Formatter\OutputFormatter', 'escape'), $messages);
  110. }
  111. foreach ($messages as $i => $line) {
  112. $messages[$i] = sprintf($template, $i, $line);
  113. }
  114. // clean this up for super.
  115. $type = $type & ~self::NUMBER_LINES & ~self::OUTPUT_RAW;
  116. }
  117. parent::write($messages, $newline, $type);
  118. }
  119. /**
  120. * Writes a message to the output.
  121. *
  122. * Handles paged output, or writes directly to the output stream.
  123. *
  124. * @param string $message A message to write to the output
  125. * @param Boolean $newline Whether to add a newline or not
  126. */
  127. public function doWrite($message, $newline)
  128. {
  129. if ($this->paging > 0) {
  130. $this->pager->doWrite($message, $newline);
  131. } else {
  132. parent::doWrite($message, $newline);
  133. }
  134. }
  135. /**
  136. * Flush and close the output pager.
  137. */
  138. private function closePager()
  139. {
  140. if ($this->paging <= 0) {
  141. $this->pager->close();
  142. }
  143. }
  144. /**
  145. * Initialize output formatter styles.
  146. */
  147. private function initFormatters()
  148. {
  149. $formatter = $this->getFormatter();
  150. $formatter->setStyle('warning', new OutputFormatterStyle('black', 'yellow'));
  151. $formatter->setStyle('aside', new OutputFormatterStyle('blue'));
  152. $formatter->setStyle('strong', new OutputFormatterStyle(null, null, array('bold')));
  153. $formatter->setStyle('return', new OutputFormatterStyle('cyan'));
  154. $formatter->setStyle('urgent', new OutputFormatterStyle('red'));
  155. $formatter->setStyle('hidden', new OutputFormatterStyle('black'));
  156. // Visibility
  157. $formatter->setStyle('public', new OutputFormatterStyle(null, null, array('bold')));
  158. $formatter->setStyle('protected', new OutputFormatterStyle('yellow'));
  159. $formatter->setStyle('private', new OutputFormatterStyle('red'));
  160. $formatter->setStyle('global', new OutputFormatterStyle('cyan', null, array('bold')));
  161. $formatter->setStyle('const', new OutputFormatterStyle('cyan'));
  162. $formatter->setStyle('class', new OutputFormatterStyle('blue', null, array('underscore')));
  163. $formatter->setStyle('function', new OutputFormatterStyle(null));
  164. // Types
  165. $formatter->setStyle('number', new OutputFormatterStyle('magenta'));
  166. $formatter->setStyle('string', new OutputFormatterStyle('green'));
  167. $formatter->setStyle('bool', new OutputFormatterStyle('cyan'));
  168. $formatter->setStyle('keyword', new OutputFormatterStyle('yellow'));
  169. $formatter->setStyle('comment', new OutputFormatterStyle('blue'));
  170. $formatter->setStyle('object', new OutputFormatterStyle('blue'));
  171. $formatter->setStyle('resource', new OutputFormatterStyle('yellow'));
  172. }
  173. }