*/
class Shell extends Application
{
- const VERSION = 'v0.8.7';
+ const VERSION = 'v0.8.17';
const PROMPT = '>>> ';
const BUFF_PROMPT = '... ';
private $outputWantsNewline = false;
private $completion;
private $tabCompletionMatchers = array();
+ private $stdoutBuffer;
+ private $prompt;
/**
* Create a new Psy Shell.
*/
public function __construct(Configuration $config = null)
{
- $this->config = $config ?: new Configuration();
- $this->cleaner = $this->config->getCodeCleaner();
- $this->loop = $this->config->getLoop();
- $this->context = new Context();
- $this->includes = array();
- $this->readline = $this->config->getReadline();
- $this->inputBuffer = array();
+ $this->config = $config ?: new Configuration();
+ $this->cleaner = $this->config->getCodeCleaner();
+ $this->loop = $this->config->getLoop();
+ $this->context = new Context();
+ $this->includes = array();
+ $this->readline = $this->config->getReadline();
+ $this->inputBuffer = array();
+ $this->stdoutBuffer = '';
parent::__construct('Psy Shell', self::VERSION);
new Command\TraceCommand(),
new Command\BufferCommand(),
new Command\ClearCommand(),
+ new Command\EditCommand($this->config->getRuntimeDir()),
// new Command\PsyVersionCommand(),
$sudo,
$hist,
new Matcher\ClassAttributesMatcher(),
new Matcher\ObjectMethodsMatcher(),
new Matcher\ObjectAttributesMatcher(),
+ new Matcher\ClassMethodDefaultParametersMatcher(),
+ new Matcher\ObjectMethodDefaultParametersMatcher(),
+ new Matcher\FunctionDefaultParametersMatcher(),
);
}
if ($this->hasCommand($input)) {
$this->readline->addHistory($input);
$this->runCommand($input);
+
continue;
}
} catch (\Exception $e) {
// Add failed code blocks to the readline history.
$this->addCodeBufferToHistory();
+
throw $e;
}
}
if ($out !== '' && !$isCleaning) {
$this->output->write($out, false, ShellOutput::OUTPUT_RAW);
$this->outputWantsNewline = (substr($out, -1) !== "\n");
+ $this->stdoutBuffer .= $out;
}
// Output buffering is done!
- if ($this->outputWantsNewline && $phase & PHP_OUTPUT_HANDLER_END) {
- $this->output->writeln(sprintf('<aside>%s</aside>', $this->config->useUnicode() ? '⏎' : '\\n'));
- $this->outputWantsNewline = false;
+ if ($phase & PHP_OUTPUT_HANDLER_END) {
+ // Write an extra newline if stdout didn't end with one
+ if ($this->outputWantsNewline) {
+ $this->output->writeln(sprintf('<aside>%s</aside>', $this->config->useUnicode() ? '⏎' : '\\n'));
+ $this->outputWantsNewline = false;
+ }
+
+ // Save the stdout buffer as $__out
+ if ($this->stdoutBuffer !== '') {
+ $this->context->setLastStdout($this->stdoutBuffer);
+ $this->stdoutBuffer = '';
+ }
}
}
{
$message = $e->getMessage();
if (!$e instanceof PsyException) {
- $message = sprintf('%s with message \'%s\'', get_class($e), $message);
+ if ($message === '') {
+ $message = get_class($e);
+ } else {
+ $message = sprintf('%s with message \'%s\'', get_class($e), $message);
+ }
}
$severity = ($e instanceof \ErrorException) ? $this->getSeverity($e) : 'error';
*/
protected function getPrompt()
{
- return $this->hasCode() ? static::BUFF_PROMPT : static::PROMPT;
+ if ($this->hasCode()) {
+ return static::BUFF_PROMPT;
+ }
+
+ return $this->config->getPrompt() ?: static::PROMPT;
}
/**
return $line;
}
- return $this->readline->readline($this->getPrompt());
+ if ($bracketedPaste = $this->config->useBracketedPaste()) {
+ printf("\e[?2004h"); // Enable bracketed paste
+ }
+
+ $line = $this->readline->readline($this->getPrompt());
+
+ if ($bracketedPaste) {
+ printf("\e[?2004l"); // ... and disable it again
+ }
+
+ return $line;
}
/**
try {
$client = $this->config->getChecker();
if (!$client->isLatest()) {
- $this->output->writeln(sprintf('New version is available (current: %s, latest: %s)',self::VERSION, $client->getLatest()));
+ $this->output->writeln(sprintf('New version is available (current: %s, latest: %s)', self::VERSION, $client->getLatest()));
}
} catch (\InvalidArgumentException $e) {
$this->output->writeln($e->getMessage());