2

I'm trying to print colored text to the console on Windows, and it requires the use of an escape character \u001B.

In my IntelliJ IDEA the code System.out.print("\u001B[92m Hello!"): prints green text " Hello!".

Unfortunately it doesn't work for the console if I run my application from CMD. I tried to use ASCII and UTF-8 encoding but it doesn't help.

For example aforementioned and following snippets

try (OutputStreamWriter writer = new OutputStreamWriter(
        System.out, 
        StandardCharsets.UTF_8)) 
{
    writer.write("\u001B[92m Hello!");
}

prints something like this <question mark in rectangle>[92m Hello!

Info: For the last example I changed the console codepage to Utf-8 with command chcp 65001 and I also run my java app with -Dfile.encoding=UTF-8 flag enabled so Java and the console use same encoding. Result is the same.

It is interesting, because I can print colored text from .bat scripts. For example the task can be done by echo <ESC>[92m Hello! where <ESC> is an escape character that can be typed to Notepad++ with keyboard combo Alt + 0 + 2 + 7.

More interesting thing is that Java correctly outputs escape character <ESC> to external file. I would be glad to know of working (preferably native) solutions to this problem.

Ivan_a_bit_Ukrainivan
  • 808
  • 1
  • 10
  • 27
  • Does your console support that type of escape syntax? – talex Jul 13 '17 at 12:51
  • Are you using Windows 10? I think such escape sequences do not work in `cmd` on older Windows versions... – aschipfl Jul 13 '17 at 12:57
  • It perfectly recognize escape character from .bat script and it recognize escape command character from manual input. So YES, it supports! Something strange happens in between java and CMD. – Ivan_a_bit_Ukrainivan Jul 13 '17 at 12:59
  • @aschipfl yes, Windows 10, Creators update. – Ivan_a_bit_Ukrainivan Jul 13 '17 at 13:00
  • @RealSkeptic Thank you for comment. It was a typo. I corrected. Unfortunately it doesn't solve the problem. Still have the same problem with escape `` character. – Ivan_a_bit_Ukrainivan Jul 13 '17 at 13:30
  • Is the program that you are running exactly that snippet, or does it have any preceding output? – RealSkeptic Jul 13 '17 at 13:38
  • @RealSkeptic no, this is the only output I have in application – Ivan_a_bit_Ukrainivan Jul 14 '17 at 07:42
  • 1
    Please don't tag a question as relating to CMD that really has nothing to do with the CMD shell. Your application has to configure the console to use virtual terminal mode. It can't be inherited from CMD, and in general that would be unreliable because your application could be started from Explorer or some other non-console application, in which CMD isn't even attached to the console. – Eryk Sun Jul 14 '17 at 23:59
  • 1
    Virtual terminal mode has nothing to do with the console's codepage. Moreover, the console's implementation of codepage 65001 (UTF-8) is extremely buggy in older versions of Windows, and even in Windows 10 it doesn't allow entering non-ASCII characters. A console application that needs to use the full range of Unicode should use the console's wide-character API (e.g. `ReadConsoleW`), which is what the CMD shell has used since the first version of NT shipped in 1993. – Eryk Sun Jul 15 '17 at 00:04

2 Answers2

1

ANSI/VT100 escape sequences do not work on all terminals. IntelliJ apparently understands them by default, but in order to get it to work on a regular Windows CMD.exe window, you need to enable the support first.

See also How to make win32 console recognize ANSI/VT100 escape sequences?

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • 1
    The OP says that the sequence works in CMD if it is run from a batch file rather than Java. – RealSkeptic Jul 13 '17 at 13:37
  • @RealSkeptic, CMD enables the VT mode of the console (conhost.exe) for itself only. When running an external program, CMD reverts the console to the mode it had at startup. So either a Java console program has to enable it, or CMD has to be started from another console program that already has VT mode enabled. The latter is better in general because CMD has a bug when running external programs in a `for` loop. It switches back to the initial console mode and doesn't restore VT mode for itself until after the loop finishes. – Eryk Sun Jul 14 '17 at 04:08
  • @eryksun That is true. CMD works fine with escape sequences in .bat scripts. Is that means that running _.bat_ scripts is treated as internal procedure for CMD? – Ivan_a_bit_Ukrainivan Jul 14 '17 at 07:53
  • @Ivan_Bereziuk, a batch script is just a different execution mode, i.e. batch mode vs single-command mode, so some behaviors change. In either case, CMD doesn't reset the console title, foreground executable name (for input aliases), input/output mode (e.g. cooked input mode and VT output mode), and input/output codepages when running an internal command. It does that for external commands because it tries to give the child console application a clean slate and doesn't assume the child restores the original console state when it exits (and obviously not if forcibly terminated). – Eryk Sun Jul 14 '17 at 17:19
0

The description of the question confused me a bit, but if you just want to print the "\" character on CMD, you just need to escape it:

eg. if you want to print "\x" you need to write it as "\\x".

See How do I print escape characters in Java

Anna P.
  • 205
  • 1
  • 3
  • 13
  • No, in my case `` character in not normally visible character. In notepad++ you can type it with "Alt + 0 + 2 + 7" combo (hold `Alt` and then successively click 0, 2,7 and release Alt button – Ivan_a_bit_Ukrainivan Jul 13 '17 at 13:02