Skip to content

Commit

Permalink
Add API for console feature detection
Browse files Browse the repository at this point in the history
  • Loading branch information
dmlloyd committed May 9, 2023
1 parent 752c564 commit c368935
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.Level;
import org.jboss.logmanager.handlers.ConsoleHandler;

import java.util.logging.Formatter;
import java.util.logging.LogRecord;
Expand Down Expand Up @@ -53,17 +54,6 @@ public ColorPatternFormatter(int darken, final String pattern) {
setPattern(pattern);
}

static final boolean trueColor = determineTrueColor();

static boolean determineTrueColor() {
final String colorterm = System.getenv("COLORTERM");
return (colorterm != null && (colorterm.contains("truecolor") || colorterm.contains("24bit")));
}

static boolean isTrueColor() {
return trueColor;
}

public void setSteps(final FormatStep[] steps) {
FormatStep[] colorSteps = new FormatStep[steps.length];
for (int i = 0; i < steps.length; i++) {
Expand Down Expand Up @@ -146,6 +136,8 @@ public String formatMessage(final LogRecord logRecord) {
static final class ColorStep implements FormatStep {
private final int r, g, b;
private final FormatStep delegate;
// capture current console state
private final boolean trueColor = ConsoleHandler.isTrueColor();

ColorStep(final FormatStep delegate, final int r, final int g, final int b, final int darken) {
this.r = r >>> darken;
Expand All @@ -155,7 +147,7 @@ static final class ColorStep implements FormatStep {
}

public void render(final Formatter formatter, final StringBuilder builder, final ExtLogRecord record) {
ColorUtil.startFgColor(builder, isTrueColor(), r, g, b);
ColorUtil.startFgColor(builder, trueColor, r, g, b);
delegate.render(formatter, builder, record);
ColorUtil.endFgColor(builder);
}
Expand Down Expand Up @@ -183,6 +175,8 @@ static final class LevelColorStep implements FormatStep {
private static final int SATURATION = 66;
private final FormatStep delegate;
private final int darken;
// capture current console state
private final boolean trueColor = ConsoleHandler.isTrueColor();

LevelColorStep(final FormatStep delegate, final int darken) {
this.delegate = delegate;
Expand All @@ -195,7 +189,7 @@ public void render(final Formatter formatter, final StringBuilder builder, final
int r = ((level < 300 ? 0 : (level - 300) * (255 - SATURATION) / 300) + SATURATION) >>> darken;
int g = ((300 - abs(level - 300)) * (255 - SATURATION) / 300 + SATURATION) >>> darken;
int b = ((level > 300 ? 0 : level * (255 - SATURATION) / 300) + SATURATION) >>> darken;
ColorUtil.startFgColor(builder, isTrueColor(), r, g, b);
ColorUtil.startFgColor(builder, trueColor, r, g, b);
delegate.render(formatter, builder, record);
ColorUtil.endFgColor(builder);
}
Expand All @@ -212,10 +206,4 @@ public boolean isCallerInformationRequired() {
return false;
}
}

static final class TrueColorHolder {
private TrueColorHolder() {}

static final boolean trueColor = ColorPatternFormatter.determineTrueColor();
}
}
46 changes: 46 additions & 0 deletions src/main/java/org/jboss/logmanager/handlers/ConsoleHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,50 @@ private static Writer wrap(final Writer writer) {
public void setOutputStream(final OutputStream outputStream) {
super.setOutputStream(wrap(outputStream));
}

/**
* Determine whether the console exists.
* If the console does not exist, then the standard output stream will be used when {@link Target#CONSOLE} is
* selected as {@linkplain #setTarget(Target) the output target}.
*
* @return {@code true} if there is a console, {@code false} otherwise
*/
public static boolean hasConsole() {
return console != null;
}

/**
* Determine whether the console supports truecolor output.
* This call may be expensive, so the result should be captured for the lifetime of any formatter making use of
* this information.
*
* @return {@code true} if the console exists and supports truecolor output; {@code false} otherwise
*/
public static boolean isTrueColor() {
if (! hasConsole()) {
return false;
}
final String colorterm = System.getenv("COLORTERM");
return colorterm != null && (colorterm.contains("truecolor") || colorterm.contains("24bit"));
}

/**
* Determine whether the console can be passively detected to support graphical output.
* This call may be expensive, so the result should be captured for the lifetime of any formatter making use of
* this information.
*
* @return {@code true} if the console exists and supports graphical output; {@code false} otherwise or if
* graphical support cannot be passively detected
*/
public static boolean isGraphicsSupportPassivelyDetected() {
if (! hasConsole()) {
return false;
}
final String term = System.getenv("TERM");
final String termProgram = System.getenv("TERM_PROGRAM");
return term != null && (term.equalsIgnoreCase("kitty")
|| term.equalsIgnoreCase("wezterm")
|| term.equalsIgnoreCase("konsole")
) || termProgram != null && termProgram.equalsIgnoreCase("wezterm");
}
}

0 comments on commit c368935

Please sign in to comment.