Skip to content

Commit

Permalink
bug #29668 [Console][VarDumper] Ignore href for PhpStorm terminal emu…
Browse files Browse the repository at this point in the history
…lator (ogizanagi)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Console][VarDumper] Ignore href for PhpStorm terminal emulator

| Q             | A
| ------------- | ---
| Branch?       | master <!-- see below -->
| Bug fix?      | yes
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | #29613 (comment)   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | N/A

So, as explained in #29613 (comment), the hyperlink feature currently breaks the PhpStorm terminal (the output stops abruptly, sometimes the whole terminal emulator freezes). Currently, a simple `dump(new \Exception());` would be enough to break it.
Hence I think we should at least ignore hyperlinks for this terminal emulator.

📝 https://youtrack.jetbrains.com/issue/IDEA-204536 feature request has been opened on JetBrains YouTrack.

Commits
-------

0f65a76 [Console][VarDumper] Ignore href for PhpStorm terminal emulator
  • Loading branch information
Robin Chalas committed Dec 29, 2018
2 parents 32a53bf + 0f65a76 commit 1d3ce9b
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
Expand Up @@ -54,6 +54,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
private $background;
private $href;
private $options = array();
private $handlesHrefGracefully;

/**
* Initializes output formatter style.
Expand Down Expand Up @@ -185,6 +186,10 @@ public function apply($text)
$setCodes = array();
$unsetCodes = array();

if (null === $this->handlesHrefGracefully) {
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR');
}

if (null !== $this->foreground) {
$setCodes[] = $this->foreground['set'];
$unsetCodes[] = $this->foreground['unset'];
Expand All @@ -199,7 +204,7 @@ public function apply($text)
$unsetCodes[] = $option['unset'];
}

if (null !== $this->href) {
if (null !== $this->href && $this->handlesHrefGracefully) {
$text = "\033]8;;$this->href\033\\$text\033]8;;\033\\";
}

Expand Down
Expand Up @@ -97,4 +97,19 @@ public function testOptions()
$this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
}
}

public function testHref()
{
$prevTerminalEmulator = getenv('TERMINAL_EMULATOR');
putenv('TERMINAL_EMULATOR');

$style = new OutputFormatterStyle();

try {
$style->setHref('idea://open/?file=/path/SomeFile.php&line=12');
$this->assertSame("\e]8;;idea://open/?file=/path/SomeFile.php&line=12\e\\some URL\e]8;;\e\\", $style->apply('some URL'));
} finally {
putenv('TERMINAL_EMULATOR'.($prevTerminalEmulator ? "=$prevTerminalEmulator" : ''));
}
}
}
Expand Up @@ -241,10 +241,17 @@ public function testFormatterHasStyles()
/**
* @dataProvider provideDecoratedAndNonDecoratedOutput
*/
public function testNotDecoratedFormatter(string $input, string $expectedNonDecoratedOutput, string $expectedDecoratedOutput)
public function testNotDecoratedFormatter(string $input, string $expectedNonDecoratedOutput, string $expectedDecoratedOutput, string $terminalEmulator = 'foo')
{
$this->assertEquals($expectedDecoratedOutput, (new OutputFormatter(true))->format($input));
$this->assertEquals($expectedNonDecoratedOutput, (new OutputFormatter(false))->format($input));
$prevTerminalEmulator = getenv('TERMINAL_EMULATOR');
putenv('TERMINAL_EMULATOR='.$terminalEmulator);

try {
$this->assertEquals($expectedDecoratedOutput, (new OutputFormatter(true))->format($input));
$this->assertEquals($expectedNonDecoratedOutput, (new OutputFormatter(false))->format($input));
} finally {
putenv('TERMINAL_EMULATOR'.($prevTerminalEmulator ? "=$prevTerminalEmulator" : ''));
}
}

public function provideDecoratedAndNonDecoratedOutput()
Expand All @@ -256,6 +263,7 @@ public function provideDecoratedAndNonDecoratedOutput()
array('<question>some question</question>', 'some question', "\033[30;46msome question\033[39;49m"),
array('<fg=red>some text with inline style</>', 'some text with inline style', "\033[31msome text with inline style\033[39m"),
array('<href=idea://open/?file=/path/SomeFile.php&line=12>some URL</>', 'some URL', "\033]8;;idea://open/?file=/path/SomeFile.php&line=12\033\\some URL\033]8;;\033\\"),
array('<href=idea://open/?file=/path/SomeFile.php&line=12>some URL</>', 'some URL', 'some URL', 'JetBrains-JediTerm'),
);
}

Expand Down
8 changes: 7 additions & 1 deletion src/Symfony/Component/VarDumper/Dumper/CliDumper.php
Expand Up @@ -59,6 +59,8 @@ class CliDumper extends AbstractDumper
'fileLinkFormat' => null,
);

private $handlesHrefGracefully;

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -431,6 +433,10 @@ protected function style($style, $value, $attr = array())
$this->colors = $this->supportsColors();
}

if (null === $this->handlesHrefGracefully) {
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR');
}

if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
$prefix = substr($value, 0, -$attr['ellipsis']);
if ('cli' === \PHP_SAPI && 'path' === $attr['ellipsis-type'] && isset($_SERVER[$pwd = '\\' === \DIRECTORY_SEPARATOR ? 'CD' : 'PWD']) && 0 === strpos($prefix, $_SERVER[$pwd])) {
Expand Down Expand Up @@ -477,7 +483,7 @@ protected function style($style, $value, $attr = array())
}

href:
if ($this->colors) {
if ($this->colors && $this->handlesHrefGracefully) {
if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], isset($attr['line']) ? $attr['line'] : 0)) {
$attr['href'] = $href;
}
Expand Down
Expand Up @@ -21,16 +21,21 @@
class CliDescriptorTest extends TestCase
{
private static $timezone;
private static $prevTerminalEmulator;

public static function setUpBeforeClass()
{
self::$timezone = date_default_timezone_get();
date_default_timezone_set('UTC');

self::$prevTerminalEmulator = getenv('TERMINAL_EMULATOR');
putenv('TERMINAL_EMULATOR');
}

public static function tearDownAfterClass()
{
date_default_timezone_set(self::$timezone);
putenv('TERMINAL_EMULATOR'.(self::$prevTerminalEmulator ? '='.self::$prevTerminalEmulator : ''));
}

/**
Expand Down

0 comments on commit 1d3ce9b

Please sign in to comment.