Skip to content

Commit

Permalink
[#846] Allow value tty for system property picocli.ansi
Browse files Browse the repository at this point in the history
Closes #846
  • Loading branch information
remkop committed Nov 21, 2019
1 parent da35ad3 commit e65530c
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 13 deletions.
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ There are also new convenience methods `Help.fullSynopsis()` and `CommandLine.ge
* [#836] (Enhancement) Add convenience methods `Help.fullSynopsis()` and `CommandLine.getHelp()`.
* [#833] (Enhancement) Non-validating ArgGroups are now automatically set to be non-exclusive. Thanks to [Andreas Deininger](https://github.com/deining) for raising this.
* [#830] (Enhancement) Enum constants can now be matched by their `toString()` as well as their `name()`. Improved error reporting. Thanks to [Henning Makholm](https://github.com/hmakholm) for the pull request.
* [#846] (Enhancement) Allow value `tty` for system property `picocli.ansi`: force picocli to emit ANSI escape characters if the process is using an interactive console.
* [#480] (DOC) Added a [Handling Errors](https://picocli.info#_handling_errors) subsection to the Executing Commands section of the user manual to show how to customize how your application deals with invalid input or business logic exceptions.
* [#813] (DOC) Clarify usage of negatable boolean `@Option` with default value "true". Thanks to [Yann ROBERT](https://github.com/YannRobert) for raising this.
* [#814] (DOC) Document how a CLI application can be packaged for distribution.
Expand Down
16 changes: 6 additions & 10 deletions docs/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3272,13 +3272,9 @@ Users may be interested in combining Jansi with https://github.com/remkop/picocl
import picocli.jansi.graalvm.AnsiConsole; // not org.fusesource.jansi.AnsiConsole
...
public static void main(String[] args) {
boolean windows = System.getProperty("os.name").toLowerCase().startsWith("win");
if (windows) { // only include in native images for Windows
AnsiConsole.systemInstall(); // enable colors on Windows
}
int exitCode = new CommandLine(new MyApp()).execute(args);
if (windows) {
AnsiConsole.systemUninstall(); // cleanup when done
int exitCode;
try (AnsiConsole ansi = AnsiConsole.windowsInstall()) {
exitCode = new CommandLine(new MyApp()).execute(args);
}
System.exit(exitCode);
}
Expand All @@ -3297,8 +3293,7 @@ This https://stackoverflow.com/a/51681675/1446916[Stack Overflow answer] has mor

CAUTION: Note that picocli's <<Heuristics for Enabling ANSI,heuristics for enabling ANSI>> currently do not include detecting whether support for Virtual Terminal / ANSI escape sequences has been turned on or off via `SetConsoleMode` or a registry change.
So just making these changes is not sufficient to let a picocli-based application show colors.
// https://github.com/remkop/picocli/issues/846
//Applications that enabled colors via `SetConsoleMode` may want to set system property `picocli.ansi` to `true`.
Applications that enabled colors via `SetConsoleMode` may want to set system property `picocli.ansi` to `tty`.
Environments that enabled colors via a Windows Registry change may want to set environment variable `CLICOLOR=1`.


Expand All @@ -3316,7 +3311,8 @@ One option is for end users to install either http://cmder.net/[Cmder], http://s
=== Forcing ANSI On/Off
You can force picocli to either always use ANSI codes or never use ANSI codes regardless of the platform:

* Setting system property `picocli.ansi` to `true` forces picocli to use ANSI codes; setting `picocli.ansi` to `false` forces picocli to *not* use ANSI codes. This may be a useful facility for users of your command line application.
* Setting system property `picocli.ansi` to `true` forces picocli to use ANSI codes; setting `picocli.ansi` to `false` forces picocli to *not* use ANSI codes. It may be useful for your users to mention this system property in the documentation for your command line application.
* Setting system property `picocli.ansi` to `tty` (case-insensitive) forces picocli to use ANSI codes only if picocli guesses that the process is using an interactive console: either `System.console() != null` or picocli guesses the application is running in a pseudo-terminal pty on a Linux emulator in Windows. Otherwise the <<Heuristics for Enabling ANSI,below heuristics>> are used to determine whether to output ANSI escape codes.
* You can decide to force disable or force enable ANSI escape codes programmatically by specifying `Ansi.ON` or `Ansi.OFF` when invoking `CommandLine.usage`.
This overrides the value of system property `picocli.ansi`. For example:

Expand Down
11 changes: 8 additions & 3 deletions src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -14555,14 +14555,19 @@ static boolean isJansiConsoleInstalled() {
}

/** Returns {@code true} if ANSI escape codes should be emitted, {@code false} otherwise.
* @return ON: {@code true}, OFF: {@code false}, AUTO: if system property {@code "picocli.ansi"} is
* defined then return its boolean value, otherwise return whether the platform supports ANSI escape codes */
* @return ON: {@code true}, OFF: {@code false}, AUTO: if system property {@code "picocli.ansi"} has value
* {@code "tty"} (case-insensitive), then return {@code true} if either {@code System.console() != null}
* or picocli guesses the application is running in a pseudo-terminal pty on a Linux emulator in Windows.
* If system property {@code "picocli.ansi"} has value {@code "true"} (case-sensitive) then return {@code true}.
* Otherwise use picocli's <a href="https://picocli.info/#_heuristics_for_enabling_ansi">Heuristics for Enabling ANSI</a>
* to determine whether the platform supports ANSI escape codes. */
public boolean enabled() {
if (this == ON) { return true; }
if (this == OFF) { return false; }
String ansi = System.getProperty("picocli.ansi");
boolean auto = ansi == null || "AUTO".equalsIgnoreCase(ansi);
return auto ? ansiPossible() : Boolean.getBoolean("picocli.ansi");
boolean tty = "TTY".equalsIgnoreCase(ansi) && (isTTY() || isPseudoTTY());
return auto ? ansiPossible() : tty || Boolean.getBoolean("picocli.ansi");
}
/**
* Returns a new Text object for this Ansi mode, encapsulating the specified string
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/picocli/CommandLineHelpAnsiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public void testAnsiEnabled() {
assertTrue(Ansi.ON.enabled());
assertFalse(Ansi.OFF.enabled());

System.setProperty("picocli.ansi", "tty");
boolean hasConsole = Ansi.calcTTY() || Ansi.isPseudoTTY();
assertEquals(hasConsole, Ansi.AUTO.enabled());

System.setProperty("picocli.ansi", "true");
assertEquals(true, Ansi.AUTO.enabled());

Expand Down

0 comments on commit e65530c

Please sign in to comment.