3

I started to learn elixir and I successfully made the iex have ansi colors. The problem is that in the terminal in vscode the output looks like garbage:

$ iex
Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
?[G?[36miex>?[0m?[0m
  • windows 10 pro
  • vscode 1.36.1
  • cmder (conemu 161206)
  • elixir 1.8.1

When I run git-for-windows' bash from cmder it works well, the colors are good.

When I run the same bash as an integrated terminal in vscode the ansi codes are printed instead of having colors.

I've never had any problem with nodejs, or anything else, only elixir related things fall apart.

This is the same for both, I don't know if it still matters:

$ elixir -e "IO.inspect :io.columns"
{:error, :enotsup}

Does anyone have any idea what does vscode differently that makes the same thing work in a different way?

indriq
  • 372
  • 1
  • 4
  • 10

1 Answers1

4

Thise ansi escape code are not supported in all Windows consoles, in particular an embedded CMD in VSCode (as detailed in Microsoft/WSL issue 1173).
Even in a git bash session done by VSCode, that bash session would still operate on top of a CMD, and not a hybrid terminal like cmder/ConEmu, able to interpret ANSI X3.64 / xterm 256 colors through hooking Windows API.

As shown here, there is an -elixir ansi_enabled false which would allow elixir to not output color escape codes.
Try an set it in the :elixir application, like doing the opposite of this example.

Application.put_env(:elixir, :ansi_enabled, false)

The other approach would be to use a VSCode console based on ConEmu/cmder, with for instance ipatalas.vscode-conemu

https://raw.githubusercontent.com/ipatalas/vscode-conemu/master/images/titlebar.png

In that kind of console, ANSI colors escape code should be displayed just fine.


The OP indriq confirms in the comments:

  • not wanting to disable colors
  • using ansicon, again an injection program:

ANSICON injects a DLL into a process, hooking its functions.
One of three methods is used to inject the DLL.

  • LoadLibrary via CreateRemoteThread for a running process.
  • LdrLoadDll via CreateRemoteThread for a 64-bit .NET AnyCPU process.
  • Adding the DLL directly to the import table, otherwise.

You can see it setup with VSCode here:

{
    ...

    "terminal.integrated.shell.windows": "C:\\Program Files\\ANSICON\\x64\\ansicon.exe",
    "terminal.integrated.shellArgs.windows": [
        "C:\\Program Files\\Git\\bin\\sh.exe",
        "--login",
        "-i"
    ]
}
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1. I know they are ansi ecape code as I mentioned it in the post. 2. I don't use cmd, I use git bash, it's in the post as well 3. I don't want to turn them off, I want to make them work in vscode the same way as they work in the same bash with cmder 4. and it's garbage because they are useless in this form :) – indriq Jul 13 '19 at 16:29
  • @indriq Sorry for the beginning of my answer, I have rewritten it to leave (for other readers) links to those escape code. I have completed said answer with an alternative approach which might enable you to keep those colors active in your Elixir script execution. – VonC Jul 13 '19 at 16:39
  • why do ansi colors work in a nodejs app in the same bash then? – indriq Jul 13 '19 at 17:03
  • I know this plugin, but it opens a new window (it works for me as well with cmder). My problem is with the integrated terminal, which opens in a panel inside vscode. – indriq Jul 13 '19 at 17:10
  • @indriq Regarding nodejs, I'll have to check how https://www.npmjs.com/package/ansi-colors, https://github.com/chalk/chalk or https://www.npmjs.com/package/colors do display their colors, but not all ansi colors are supported in all parts of VSCode, like the high-intensity ones (https://github.com/microsoft/vscode/issues/21423#issuecomment-373966489). Which is problematic for my own little utility (not nodejs-related) https://github.com/VonC/batcolors, since I use them (https://github.com/VonC/batcolors/blob/d099c1b84cbb21474c5e80a97d3ff84a380f3c9b/echos.bat#L21-L25) – VonC Jul 13 '19 at 18:26
  • I've found one more interesting thing. If I run `curl http://wttr.in/` in the same window where the ansi codes don't work in elixir, the colors are displayed well and they are ansi codes. It seems that before the output is displayed in elixir the escape character gets... well.. escaped, therefore it's not really an ansi color sequence that arrives to the terminal, so there are no ansi codes to transform into colors, just simple characters. – indriq Jul 13 '19 at 23:31
  • In nodejs I haven't used any libraries for testing I've just printed out a character sequence with ansi colors in it ([link](https://gist.github.com/indriq/f91df63b41c7d5b2b92a6425b7a899bb)) – indriq Jul 13 '19 at 23:41
  • @indriq OK. Maybe the escape chearacter sequence used by Elixir is somehow different? (https://github.com/elixir-lang/elixir/blob/c6c788f1e1648f03e9bb6ea1cb2148a1de6e9bca/lib/elixir/lib/io/ansi.ex#L7). Would https://github.com/elixir-lang/elixir/blob/02a327d3c42fc2d22f1e548482db8173a7543687/lib/logger/test/logger/backends/console_test.exs work in a regular CMD console? OR, as you say, VSCode escape the escape sequence... – VonC Jul 14 '19 at 03:53
  • elixir's escape character is the same, since it works in the bash running inside conemu. (and \e = 27) I tried this: `IO.puts([27] ++ '[32mcolor test' ++ [27] ++ '[0m')` In vscode it displayed the ascii color codes with the \e character being escaped, replacing it with a question mark, probably because it's a non-printable character. I tried `IO.binwrite/2` as well, same result. If binwrite really spits out the raw bytes without touching them, I have no idea what's happening here... :) – indriq Jul 15 '19 at 05:53
  • @indriq I agree. I guess my answer as it currently stands is a crude workaround (disable colors). But I don't have something more satisfying at the moment. – VonC Jul 15 '19 at 06:12
  • Well, if I need colors disabling them is not a workaround :) I've found a workaround: there's a small program called ansicon which does the trick. I don't know what it does, but I can have colors with elixir inside vscode. It's not a solution, but it works and it's enough for me now. Thanks for trying to help :) – indriq Jul 15 '19 at 06:20
  • @indriq Right. "workaround" was not the right term! I have edited the answer to make your view more visible and document Ansicon. – VonC Jul 15 '19 at 07:18