[ansiconsole] provide API to check if ANSI is enabled
When executing a program (e.g. maven, cucumber,...) one usually want to enable a "monocrome" mode if ansi is disabled.
There currently is org.eclipse.ui.internal.console.ansi.preferences.AnsiConsolePreferenceUtils.isAnsiConsoleEnabled() but this is private and not accessible to programs.
It would therefore be good to have a way to check if ansi is enabled in general and of course for a console instance @mihnita I think we once already discussed this and decided to "do it sometime later" but it seems it havent happened yet.
Sorry for the delay, I'm in a middle of an CLDR / ICU release :-)
But I also spend some time digging on what is the best way to make that happen.
It is easy to make something like the above API public, but most applications will be unable to access it. We would need something that is Eclipse-aware to access that API, and to (somehow) pass it to maven / cucumber / etc.
So I looked to see if there is some standard way that any application might detect if ANSI escapes are enabled / supported. And unfortunately there is nothing.
Most common way for applications to determine if they should use color or not is to call istty, so if the output is redirected they don't, otherwise they do.
But the Eclipse console always answers false to that call.
One option would be to "fake it", and have it return true if AnsiConsole is enabled, and false if it is not.
But istty is not a direct indication of colors being supported, but about redirect.
So this might introduce other bugs.
Another option would be to set a certain environment variable (and "inject" that in all applications). But I was unable to find any widely supported standard.
- Some apps check the
TERMvariable to "sniff" the terminal kind, or leave that toterminfo - FreeBSD have
CLICOLORandCOLORTERM(I don't know how they work and how they interact) - There is an effort to standardize
NO_COLORandCLICOLOR_FORCE, with some adoption (https://no-color.org/, https://bixense.com/clicolors/) - Also
NO_COLOR/FORCE_COLOR, with less traction (https://force-color.org/)
I think the most promising are NO_COLOR and CLICOLOR_FORCE
What do you think?
And is there a way to inject a variable in all executions? I hope there is... if you know what that is, it would save me some time, otherwise I can do some digging.
BTW, we already have something in the maven launcher.
It tells maven what to do (passes -Dstyle.color=auto/never/always)
And auto detects if ANSI is enabled or not and "resolves" it to never/always.
Does it by using IPreferencesService:
private static final String ANSI_SUPPORT_QUALIFIER = "org.eclipse.ui.console"; //$NON-NLS-1$
private static final String ANSI_SUPPORT_KEY = "ANSI_support_enabled"; //$NON-NLS-1$
return preferencesService.getBoolean(ANSI_SUPPORT_QUALIFIER, ANSI_SUPPORT_KEY, true, null);
(https://github.com/eclipse-m2e/m2e-core/blob/248d8fce98037e865120e58afffaf911e471d374/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java#L488)
It is easy to make something like the above API public, but most applications will be unable to access it. We would need something that is Eclipse-aware to access that API, and to (somehow) pass it to maven / cucumber / etc.
I would not expect it to work "automatically" so ther will always be some "glue" between Eclipse<->Running Application in console)
BTW, we already have something in the maven launcher. It tells maven what to do (passes -Dstyle.color=auto/never/always) And auto detects if ANSI is enabled or not and "resolves" it to never/always. Does it by using IPreferencesService:
Yes thats what I mean, if we ever change the preference (beside that its quite brittle to write) this will break, so at best we should have something that can be accessed by code without require to use magic string constants and preference services.
Sorry, I spent some time on it over the week-end.
I was hoping to get a pull request.
But I discovered that all the AnsiConsole stuff is in org.eclipse.ui.internal.console.ansi, there is nothing public, not even one class. And I got stuck.
So in the end I decided that it is best to ask for advice: what would be the best way to expose this?
I can think of a few options:
- Add some method(s) to an existing class in
org.eclipse.ui.console(maybeIOConsole?) - Add a new class
AnsiConsoleorAnsiConsoleSettings / Configinorg.eclipse.ui.consoleororg.eclipse.ui.console.ansiThat would allow some growth in the future, to expose other settings. - Expose these settings using a command (some kind of
CommandManager...getCommand...executeWithChecks) Is that something recommended / common in the Eclipse world?
Thank you very much, Mihai
I think some new method in IOConsole would be suitable, as ANSI support is build in now.
Thank you, I will prepare a PR tonight (US Pacific Time :-)