Revision 1294 | Blame | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed
<?php/** This file is part of Psy Shell.** (c) 2012-2023 Justin Hileman** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/namespace Psy\Output;use Symfony\Component\Console\Formatter\OutputFormatterInterface;use Symfony\Component\Console\Formatter\OutputFormatterStyle;/*** An output Theme, which controls prompt strings, formatter styles, and compact output.*/class Theme{const MODERN_THEME = []; // Defaults :)const COMPACT_THEME = ['compact' => true,];const CLASSIC_THEME = ['compact' => true,'prompt' => '>>> ','bufferPrompt' => '... ','replayPrompt' => '--> ','returnValue' => '=> ',];const DEFAULT_STYLES = ['info' => ['white', 'blue', ['bold']],'warning' => ['black', 'yellow'],'error' => ['white', 'red', ['bold']],'whisper' => ['gray'],'aside' => ['blue'],'strong' => [null, null, ['bold']],'return' => ['cyan'],'urgent' => ['red'],'hidden' => ['black'],// Visibility'public' => [null, null, ['bold']],'protected' => ['yellow'],'private' => ['red'],'global' => ['cyan', null, ['bold']],'const' => ['cyan'],'class' => ['blue', null, ['underscore']],'function' => [null],'default' => [null],// Types'number' => ['magenta'],'integer' => ['magenta'],'float' => ['yellow'],'string' => ['green'],'bool' => ['cyan'],'keyword' => ['yellow'],'comment' => ['blue'],'code_comment' => ['gray'],'object' => ['blue'],'resource' => ['yellow'],// Code-specific formatting'inline_html' => ['cyan'],];const ERROR_STYLES = ['info', 'warning', 'error', 'whisper', 'class'];private $compact = false;private $prompt = '> ';private $bufferPrompt = '. ';private $replayPrompt = '- ';private $returnValue = '= ';private $grayFallback = 'blue';private $styles = [];/*** @param string|array $config theme name or config options*/public function __construct($config = 'modern'){if (\is_string($config)) {switch ($config) {case 'modern':$config = static::MODERN_THEME;break;case 'compact':$config = static::COMPACT_THEME;break;case 'classic':$config = static::CLASSIC_THEME;break;default:\trigger_error(\sprintf('Unknown theme: %s', $config), \E_USER_NOTICE);$config = static::MODERN_THEME;break;}}if (!\is_array($config)) {throw new \InvalidArgumentException('Invalid theme config');}foreach ($config as $name => $value) {switch ($name) {case 'compact':$this->setCompact($value);break;case 'prompt':$this->setPrompt($value);break;case 'bufferPrompt':$this->setBufferPrompt($value);break;case 'replayPrompt':$this->setReplayPrompt($value);break;case 'returnValue':$this->setReturnValue($value);break;case 'grayFallback':$this->setGrayFallback($value);break;}}$this->setStyles($config['styles'] ?? []);}/*** Enable or disable compact output.*/public function setCompact(bool $compact){$this->compact = $compact;}/*** Get whether to use compact output.*/public function compact(): bool{return $this->compact;}/*** Set the prompt string.*/public function setPrompt(string $prompt){$this->prompt = $prompt;}/*** Get the prompt string.*/public function prompt(): string{return $this->prompt;}/*** Set the buffer prompt string (used for multi-line input continuation).*/public function setBufferPrompt(string $bufferPrompt){$this->bufferPrompt = $bufferPrompt;}/*** Get the buffer prompt string (used for multi-line input continuation).*/public function bufferPrompt(): string{return $this->bufferPrompt;}/*** Set the prompt string used when replaying history.*/public function setReplayPrompt(string $replayPrompt){$this->replayPrompt = $replayPrompt;}/*** Get the prompt string used when replaying history.*/public function replayPrompt(): string{return $this->replayPrompt;}/*** Set the return value marker.*/public function setReturnValue(string $returnValue){$this->returnValue = $returnValue;}/*** Get the return value marker.*/public function returnValue(): string{return $this->returnValue;}/*** Set the fallback color when "gray" is unavailable.*/public function setGrayFallback(string $grayFallback){$this->grayFallback = $grayFallback;}/*** Set the shell output formatter styles.** Accepts a map from style name to [fg, bg, options], for example:** [* 'error' => ['white', 'red', ['bold']],* 'warning' => ['black', 'yellow'],* ]** Foreground, background or options can be null, or even omitted entirely.*/public function setStyles(array $styles){foreach (\array_keys(static::DEFAULT_STYLES) as $name) {$this->styles[$name] = $styles[$name] ?? static::DEFAULT_STYLES[$name];}}/*** Apply the current output formatter styles.*/public function applyStyles(OutputFormatterInterface $formatter, bool $useGrayFallback){foreach (\array_keys(static::DEFAULT_STYLES) as $name) {$formatter->setStyle($name, new OutputFormatterStyle(...$this->getStyle($name, $useGrayFallback)));}}/*** Apply the current output formatter error styles.*/public function applyErrorStyles(OutputFormatterInterface $errorFormatter, bool $useGrayFallback){foreach (static::ERROR_STYLES as $name) {$errorFormatter->setStyle($name, new OutputFormatterStyle(...$this->getStyle($name, $useGrayFallback)));}}private function getStyle(string $name, bool $useGrayFallback): array{return \array_map(function ($style) use ($useGrayFallback) {return ($useGrayFallback && $style === 'gray') ? $this->grayFallback : $style;}, $this->styles[$name]);}}