Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated terminal (cygwin64 bash) not rendering color escape codes on php output #22616

Closed
hazzlewis opened this issue Mar 14, 2017 · 24 comments
Assignees
Labels
info-needed Issue requires more information from poster terminal Integrated terminal issues windows VS Code on Windows issues

Comments

@hazzlewis
Copy link

  • VSCode Version: 1.10.2
  • OS Version: Windows 10.0.14393 Build 14393

Using cygwin64 bash.exe as integrated terminal like so:
image

Standard color prompt works just fine:
image

However executing a PHP script, color escape codes are not interpreted properly, resulting in garbled output. Specifically, running Laravel's artisan command:
image

This same command works as expected in mintty:
image

Am i doing anything wrong or is this a bug?

@hazzlewis hazzlewis changed the title Integrated terminal (cygwin64 bash) escaping php output Integrated terminal (cygwin64 bash) not rendering color escape codes on php output Mar 14, 2017
@Tyriar
Copy link
Member

Tyriar commented Mar 14, 2017

Looks like \x1b is being translated to ? somewhere along the way.

@Tyriar Tyriar added terminal Integrated terminal issues windows VS Code on Windows issues labels Mar 14, 2017
@Tyriar
Copy link
Member

Tyriar commented Mar 14, 2017

@hazzlewis is there any trick to getting the cygwin exe running in the terminal? It's telling me /usr/bin/bash wasn't found after a fresh install and using your settings?

@Tyriar Tyriar added the info-needed Issue requires more information from poster label Mar 14, 2017
@hazzlewis
Copy link
Author

hazzlewis commented Mar 14, 2017 via email

@hazzlewis
Copy link
Author

hazzlewis commented Mar 15, 2017

Interestingly, it works absolutely fine when executing the command on a VM. Apparently the issue is only occurring when executing it locally. Maybe it's something to do with Windows vs Linux.

Local:

harry@Harrys-Laptop /cygdrive/c/Users/harry/vc/pub (master)
$ php -v
PHP 7.1.1 (cli) (built: Jan 18 2017 18:51:14) ( ZTS MSVC14 (Visual C++ 2015) x86 )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Xdebug v2.5.0, Copyright (c) 2002-2016, by Derick Rethans

VM:

vagrant@vagrant:~$ php -v
PHP 7.0.15-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.15-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies

@Tyriar
Copy link
Member

Tyriar commented Mar 17, 2017

@hazzlewis a lot more stuff happens to get the terminal working on Windows so that's not surprising. Do you see the same problem if run through Git Bash? (install git and then add "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe")

@hazzlewis
Copy link
Author

Yup, same dice... 👎 :(

image

@Tyriar
Copy link
Member

Tyriar commented Mar 21, 2017

Ping @rprichard, potential issue with winpty (or the PHP cli?).

@rprichard
Copy link

Looks like \x1b is being translated to ? somewhere along the way.

winpty translates 'x1b' to '?', but that's expected (rprichard/winpty#47).

It's probably an incorrect environment setting. I see that the issue reproduces if TERM is set to xterm. That shouldn't happen -- VSCode should leave TERM unset, then Cygwin bash.exe should set it to cygwin.

@hazzlewis
Copy link
Author

hazzlewis commented Mar 22, 2017 via email

@rprichard
Copy link

@hazzlewis Yes, I'm only able to reproduce the issue by manually setting TERM incorrectly, so I need more info. e.g. What is your TERM variable set to?

@hazzlewis
Copy link
Author

hazzlewis commented Mar 22, 2017 via email

@hazzlewis
Copy link
Author

Nevermind. TERM is cygwin:
image

Oddly, in git bash TERM is also cygwin:
image

@rprichard
Copy link

@hazzlewis Do you have ANSICON or ConEmuANSI environment variables set?

Here's what I see on Windows 7 64-bit in VSCode 1.10.2 with C:\cygwin64\bin\bash.exe --login as my integrated shell:

rprichard@VBWIN7 /cygdrive/c/Users/rprichard/blog
$ cmd /c set TERM
TERM=cygwin

rprichard@VBWIN7 /cygdrive/c/Users/rprichard/blog
$ cmd /c set ANSICON
Environment variable ANSICON not defined

rprichard@VBWIN7 /cygdrive/c/Users/rprichard/blog
$ cmd /c set ConEmuANSI
Environment variable ConEmuANSI not defined

rprichard@VBWIN7 /cygdrive/c/Users/rprichard/blog
$ php -v
PHP 7.1.3 (cli) (built: Mar 14 2017 23:46:26) ( ZTS MSVC14 (Visual C++ 2015) x86 )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

rprichard@VBWIN7 /cygdrive/c/Users/rprichard/blog
$ php artisan
Laravel Framework 5.4.16

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
...

(The php artisan output is uncolored.)

Details:

I created a new Laravel project with these steps:

  • Install PHP 7.1.3 native x86: PHP 7.1.3 (cli) (built: Mar 14 2017 23:46:26) ( ZTS MSVC14 (Visual C++ 2015) x86 ).

  • Create a C:\Windows\php.ini:

    extension_dir = "C:\php-7.1.3\ext"
    extension=php_openssl.dll
    extension=php_mbstring.dll
    
  • Install composer using the setup EXE: Composer version 1.4.1 2017-03-10 09:29:45

  • Create a new Laravel project with composer create-project --prefer-dist laravel/laravel blog.

It looks like the color support decision is made by vendor\symfony\console\Output\StreamOutput.php:

    protected function hasColorSupport()
    {
        if (DIRECTORY_SEPARATOR === '\\') {
            return
                '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
                || false !== getenv('ANSICON')
                || 'ON' === getenv('ConEmuANSI')
                || 'xterm' === getenv('TERM');
        }

        return function_exists('posix_isatty') && @posix_isatty($this->stream);
    }

There are similar pieces of logic in:

  • vendor\jakub-onderka\php-console-color\src\JakubOnderka\PhpConsoleColor\ConsoleColor.php
  • vendor\sebastian\environment\src\Console.php
  • vendor\symfony\var-dumper\Dumper\CliDumper.php

For Windows, color escapes are enabled if ANSICON is set to anything, if ConEmuANSI is set to ON, if TERM is set to xterm, or if the Windows version is exactly 10.0.10586. (That last part is suspicious to me in a few ways: (a) there are newer versions of Windows 10, and (b) the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode flag is unsupported with the Win10 legacy console, and (c) the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode flag isn't always turned on).

@rprichard
Copy link

@hazzlewis Here's another thing to try: instead of using VSCode, start your shell via Start -> Run:

C:\cygwin64\bin\bash.exe /bin/xhere /bin/bash

Then run php artisan as before. There are three outcomes I can think of:

  • Broken (no color, visible escape sequences)
  • Uncolored
  • Colored

I'm still interested in whether your ANSICON and ConEmuANSI environment variables are set.

@hazzlewis
Copy link
Author

hazzlewis commented Mar 22, 2017 via email

@rprichard
Copy link

Using both git bash and cygwin it works absolutely fine in their own mintty consoles. Just doesnt work in vscode

mintty isn't the Windows console -- it's a Cygwin-based VT/100 terminal emulator. I'm not surprised that it works fine in mintty. mintty will set TERM to xterm, and then the PHP-based components will decide to write VT/100 color escapes, which mintty will successfully process.

The issue is why these same PHP-based components decide to write escapes to a Windows console, where they aren't interpreted.

So, to reinterate:

  • My guess so far is that you've somehow got ANSICON or ConEmuANSI set. Maybe winpty needs to clear one or both of these variables.

  • It would be interesting to see what happens if you start a console by running C:\cygwin64\bin\bash.exe /bin/xhere /bin/bash via Start -> Run. This will start a Windows console, not the Cygwin terminal emulator. (If you have ConEmu installed, then it might start ConEmu instead of an ordinary console.)

It would also be interesting to know if you have the Use legacy console option set. http://www.isunshare.com/windows-10/enable-use-legacy-console-for-command-prompt-in-windows-10.html

It would be interesting to know if you have ConEmu installed.

@hazzlewis
Copy link
Author

hazzlewis commented Mar 23, 2017

Result when using system console C:\cygwin64\bin\bash.exe /bin/xhere /bin/bash via Start -> Run:
image

Legacy console is/was disabled:
image

@hazzlewis
Copy link
Author

Further to the above, both ANSICON and ConEmuANSI are unset.

@hazzlewis
Copy link
Author

hazzlewis commented Mar 24, 2017

Ok so i just looked at that function you found. Sure enough, thats whats doing it. Looks like a bug which has since been fixed in that symfony component because in my environment (2.8.3), the line reads:

...
0 >= version_compare('10.0.10586', PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD)
...

So, the statement is always evaluating true on the first condition because my build 10.0.14393 is greater than 10.0.10586. I.e.:

php > var_dump(0 >= version_compare('10.0.10586','10.0.14393'));
php shell code:1:
bool(true)

So i guess my remaining questions are:

  1. Is there any way to fix colorization when executing the command through the integrated terminal on my local system? (If, still in the integrated shell i SSH into a VM or remote machine, colorized output works just fine. Why is that?):
    image

  2. How can i run an integrated xterm terminal, if its possible ??

@Tyriar
Copy link
Member

Tyriar commented Mar 29, 2017

You could try setting TERM=xterm or TERM=xterm-256color after launching the terminal? If that doesn't work I don't think there's much that can be done about it in VS Code since it's happening in a regular command prompt.

@Tyriar Tyriar closed this as completed Mar 29, 2017
@rprichard
Copy link

It looks like the PHP-based code needs to be fixed to stop using escapes on Win10 when they aren't supported.

Ideally, though, something would turn on the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag, and then color would work. This might be something winpty ought to do. It's issue rprichard/winpty#92. My impression was that conhost/cmd/powershell leave the flag off, though, for backwards-compatibility? This Win10 mode flag is new, so maybe the proper convention is still being worked out. It seems inconvenient that every command-line program needs to set/restore that mode flag.

Alternatively, some command-line programs notice that they're writing to a Windows console (rather than a Unix tty) and use SetConsoleTextAttribute instead of escapes.

"Some programs" includes all Cygwin programs, so if you're using Cygwin SSH into a Cygwin SSH server, that's why color works. The PHP-based code will print escapes, which will reach the SSH client, and finally the Cygwin DLL will interpret color escapes into calls to SetConsoleTextAttribute.

If you use WSL SSH (into anything), then WSL turns on ENABLE_VIRTUAL_TERMINAL_PROCESSING, so conhost interprets the color escapes.

There's work to do on this issue, but it's not much of a VSCode issue.

@rprichard
Copy link

BTW, this comment in libuv is relevant. I see code in libuv to enable ENABLE_VIRTUAL_TERMINAL_PROCESSING.

@rprichard
Copy link

Here are PHP-related bug reports w.r.t. ENABLE_VIRTUAL_TERMINAL_PROCESSING:

@idbartosz
Copy link

PHPunit has same problem with colors, I've had to pipe the output to the cat command like this:
phpunit test --colors=always | cat

pipecat

@vscodebot vscodebot bot locked and limited conversation to collaborators Nov 17, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
info-needed Issue requires more information from poster terminal Integrated terminal issues windows VS Code on Windows issues
Projects
None yet
Development

No branches or pull requests

4 participants