/** * 显示问题的提示信息 */ protected function writePrompt() { $text = $this->question->getQuestion(); $default = $this->question->getDefault(); switch (true) { case null === $default: $text = sprintf(' <info>%s</info>:', $text); break; case $this->question instanceof Confirmation: $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no'); break; case $this->question instanceof Choice && $this->question->isMultiselect(): $choices = $this->question->getChoices(); $default = explode(',', $default); foreach ($default as $key => $value) { $default[$key] = $choices[trim($value)]; } $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, implode(', ', $default)); break; case $this->question instanceof Choice: $choices = $this->question->getChoices(); $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $choices[$default]); break; default: $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $default); } $this->output->writeln($text); if ($this->question instanceof Choice) { $width = max(array_map('strlen', array_keys($this->question->getChoices()))); foreach ($this->question->getChoices() as $key => $value) { $this->output->writeln(sprintf(" [<comment>%-{$width}s</comment>] %s", $key, $value)); } } $this->output->write(' > '); }
/** * 包装过程回调来添加调试输出 * @param Output $output * @param ThinkProcess $process * @param callable|null $callback * @return callable */ public function wrapCallback(Output $output, ThinkProcess $process, $callback = null) { /** @var Debug $formatter */ $formatter = $this->getHelperSet()->get('debug_formatter'); return function ($type, $buffer) use($output, $process, $callback, $formatter) { $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), ThinkProcess::ERR === $type)); if (null !== $callback) { call_user_func($callback, $type, $buffer); } }; }
/** * 自动完成问题 * @param Output $output * @param OutputQuestion $question * @param $inputStream * @return string */ private function autocomplete(Output $output, OutputQuestion $question, $inputStream) { $autocomplete = $question->getAutocompleterValues(); $ret = ''; $i = 0; $ofs = -1; $matches = $autocomplete; $numMatches = count($matches); $sttyMode = shell_exec('stty -g'); shell_exec('stty -icanon -echo'); $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); while (!feof($inputStream)) { $c = fread($inputStream, 1); if ("" === $c) { if (0 === $numMatches && 0 !== $i) { $i--; $output->write("[1D"); } if ($i === 0) { $ofs = -1; $matches = $autocomplete; $numMatches = count($matches); } else { $numMatches = 0; } $ret = substr($ret, 0, $i); } elseif ("" === $c) { $c .= fread($inputStream, 2); if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { if ('A' === $c[2] && -1 === $ofs) { $ofs = 0; } if (0 === $numMatches) { continue; } $ofs += 'A' === $c[2] ? -1 : 1; $ofs = ($numMatches + $ofs) % $numMatches; } } elseif (ord($c) < 32) { if ("\t" === $c || "\n" === $c) { if ($numMatches > 0 && -1 !== $ofs) { $ret = $matches[$ofs]; $output->write(substr($ret, $i)); $i = strlen($ret); } if ("\n" === $c) { $output->write($c); break; } $numMatches = 0; } continue; } else { $output->write($c); $ret .= $c; $i++; $numMatches = 0; $ofs = 0; foreach ($autocomplete as $value) { if (0 === strpos($value, $ret) && $i !== strlen($value)) { $matches[$numMatches++] = $value; } } } $output->write("[K"); if ($numMatches > 0 && -1 !== $ofs) { $output->write("7"); $output->write('<hl>' . substr($matches[$ofs], $i) . '</hl>'); $output->write("8"); } } shell_exec(sprintf('stty %s', $sttyMode)); return $ret; }
/** * 输出内容 * @param string $content * @param bool $decorated */ protected function write($content, $decorated = false) { $this->output->write($content, false, $decorated ? Output::OUTPUT_NORMAL : Output::OUTPUT_RAW); }