Skip to content

Commit

Permalink
update net.minecrell:terminalconsoleappender
Browse files Browse the repository at this point in the history
update net.minecrell:terminalconsoleappender
  • Loading branch information
Ecdcaeb committed Jan 1, 2025
1 parent 5e70691 commit c7f4e1d
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

/**
* A simplified version of {@link HighlightConverter} that uses
* {@link TerminalConsoleAppender} to detect if Ansi escape codes can be used
* {@link TerminalConsoleAppender} to detect if ANSI escape codes can be used
* to highlight errors and warnings in the console.
*
* <p>If configured, it will mark all logged errors with a red color and all
Expand All @@ -55,9 +55,9 @@
@PerformanceSensitive("allocation")
public class HighlightErrorConverter extends LogEventPatternConverter
{
private static final String ANSI_RESET = "\u001B[39;0m";
private static final String ANSI_ERROR = "\u001B[31;1m";
private static final String ANSI_WARN = "\u001B[33;1m";
private static final String ANSI_RESET = "\u001B[m";
private static final String ANSI_ERROR = "\u001B[31;1m"; // Bold Red
private static final String ANSI_WARN = "\u001B[33;1m"; // Bold Yellow

private final List<PatternFormatter> formatters;

Expand Down Expand Up @@ -142,8 +142,7 @@ public boolean handlesThrowable()
* @param options The pattern options
* @return The new instance
*/
@Nullable
public static HighlightErrorConverter newInstance(Configuration config, String[] options)
public static @Nullable HighlightErrorConverter newInstance(Configuration config, String[] options)
{
if (options.length != 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,16 @@
*
* @see <a href="http://minecraft.gamepedia.com/Formatting_codes">
* Formatting Codes</a>
* @deprecated Minecraft-specific. Also, legacy formatting codes are deprecated
* and do not natively allow specifying RGB colors. Consider implementing
* native support for the (JSON) chat components of your platform instead.
* For more information, see
* <a href="https://github.com/Minecrell/TerminalConsoleAppender/issues/18">issue #18</a>.
*/
@Plugin(name = "minecraftFormatting", category = PatternConverter.CATEGORY)
@ConverterKeys({ "minecraftFormatting" })
@PerformanceSensitive("allocation")
@Deprecated
public class MinecraftFormattingConverter extends LogEventPatternConverter
{

Expand All @@ -77,34 +83,34 @@ public class MinecraftFormattingConverter extends LogEventPatternConverter

private static final boolean KEEP_FORMATTING = PropertiesUtil.getProperties().getBooleanProperty(KEEP_FORMATTING_PROPERTY);

private static final String ANSI_RESET = "\u001B[m";
static final String ANSI_RESET = "\u001B[m";

private static final char COLOR_CHAR = '\u00A7'; // §
private static final char COLOR_CHAR = '§';
private static final String LOOKUP = "0123456789abcdefklmnor";

private static final String[] ansiCodes = new String[] {
"\u001B[0;30m", // Black §0
"\u001B[0;34m", // Dark Blue §1
"\u001B[0;32m", // Dark Green §2
"\u001B[0;36m", // Dark Aqua §3
"\u001B[0;31m", // Dark Red §4
"\u001B[0;35m", // Dark Purple §5
"\u001B[0;33m", // Gold §6
"\u001B[0;37m", // Gray §7
"\u001B[0;30;1m", // Dark Gray §8
"\u001B[0;34;1m", // Blue §9
"\u001B[0;32;1m", // Green §a
"\u001B[0;36;1m", // Aqua §b
"\u001B[0;31;1m", // Red §c
"\u001B[0;35;1m", // Light Purple §d
"\u001B[0;33;1m", // Yellow §e
"\u001B[0;37;1m", // White §f
"\u001B[5m", // Obfuscated §k
"\u001B[21m", // Bold §l
"\u001B[9m", // Strikethrough §m
"\u001B[4m", // Underline §n
"\u001B[3m", // Italic §o
ANSI_RESET, // Reset §r
"\u001B[0;30m", // Black §0
"\u001B[0;34m", // Dark Blue §1
"\u001B[0;32m", // Dark Green §2
"\u001B[0;36m", // Dark Aqua §3
"\u001B[0;31m", // Dark Red §4
"\u001B[0;35m", // Dark Purple §5
"\u001B[0;33m", // Gold §6
"\u001B[0;37m", // Gray §7
"\u001B[0;30;1m", // Dark Gray §8
"\u001B[0;34;1m", // Blue §9
"\u001B[0;32;1m", // Green §a
"\u001B[0;36;1m", // Aqua §b
"\u001B[0;31;1m", // Red §c
"\u001B[0;35;1m", // Light Purple §d
"\u001B[0;33;1m", // Yellow §e
"\u001B[0;37;1m", // White §f
"\u001B[5m", // Obfuscated §k
"\u001B[21m", // Bold §l
"\u001B[9m", // Strikethrough §m
"\u001B[4m", // Underline §n
"\u001B[3m", // Italic §o
ANSI_RESET, // Reset §r
};

private final boolean ansi;
Expand Down Expand Up @@ -143,7 +149,7 @@ public void format(LogEvent event, StringBuilder toAppendTo)
format(content, toAppendTo, start, ansi && TerminalConsoleAppender.isAnsiSupported());
}

private static void format(String s, StringBuilder result, int start, boolean ansi)
static void format(String s, StringBuilder result, int start, boolean ansi)
{
int next = s.indexOf(COLOR_CHAR);
int last = s.length() - 1;
Expand Down Expand Up @@ -195,8 +201,7 @@ private static void format(String s, StringBuilder result, int start, boolean an
*
* @see MinecraftFormattingConverter
*/
@Nullable
public static MinecraftFormattingConverter newInstance(Configuration config, String[] options)
public static @Nullable MinecraftFormattingConverter newInstance(Configuration config, String[] options)
{
if (options.length < 1 || options.length > 2)
{
Expand All @@ -214,4 +219,5 @@ public static MinecraftFormattingConverter newInstance(Configuration config, Str
boolean strip = options.length > 1 && "strip".equals(options[1]);
return new MinecraftFormattingConverter(formatters, strip);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package net.minecraftforge.server.terminalconsole;

import org.apache.logging.log4j.LogManager;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jline.reader.Completer;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.UserInterruptException;
import org.jline.terminal.Terminal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
* A simple, optional base implementation of a basic console input command
* reader using {@link TerminalConsoleAppender}. Once started, it displays
* a command prompt ("{@code > }") and reads input commands from the console.
*
* <p><strong>Usage:</strong> Extend this class and implement the abstract
* methods for your application. Consider overriding
* {@link #buildReader(LineReaderBuilder)} to add further features to the
* console (e.g. call {@link LineReaderBuilder#completer(Completer)} with
* a custom completer to provide command completion).</p>
*/
public abstract class SimpleTerminalConsole {

/**
* Determines if the application is still running and accepting input.
*
* @return {@code true} to continue reading input
*/
protected abstract boolean isRunning();

/**
* Run a command entered in the console.
*
* @param command The command line to run
*/
protected abstract void runCommand(String command);

/**
* Shutdown the application and perform a clean exit.
*
* <p>This is called if the application receives SIGINT while reading input,
* e.g. when pressing CTRL+C on most terminal implementations.</p>
*/
protected abstract void shutdown();

/**
* Process an input line entered through the console.
*
* <p>The default implementation trims leading and trailing whitespace
* from the input and skips execution if the command is empty.</p>
*
* @param input The input line
*/
protected void processInput(String input) {
String command = input.trim();
if (!command.isEmpty()) {
runCommand(command);
}
}

/**
* Configures the {@link LineReaderBuilder} and {@link LineReader} with
* additional options.
*
* <p>Override this method to make further changes, (e.g. call
* {@link LineReaderBuilder#appName(String)} or
* {@link LineReaderBuilder#completer(Completer)}).</p>
*
* <p>The default implementation sets some opinionated default options,
* which are considered to be appropriate for most applications:</p>
*
* <ul>
* <li>{@link LineReader.Option#DISABLE_EVENT_EXPANSION}: JLine implements
* <a href="http://www.gnu.org/software/bash/manual/html_node/Event-Designators.html">
* Bash's Event Designators</a> by default. These usually do not
* behave as expected in a simple command environment, so it's
* recommended to disable it.</li>
* <li>{@link LineReader.Option#INSERT_TAB}: By default, JLine inserts
* a tab character when attempting to tab-complete on empty input.
* It is more intuitive to show a list of commands instead.</li>
* </ul>
*
* @param builder The builder to configure
* @return The built line reader
*/
protected LineReader buildReader(LineReaderBuilder builder) {
LineReader reader = builder.build();
reader.setOpt(LineReader.Option.DISABLE_EVENT_EXPANSION);
reader.unsetOpt(LineReader.Option.INSERT_TAB);
return reader;
}

/**
* Start reading commands from the console.
*
* <p>Note that this method won't return until one of the following
* conditions are met:</p>
*
* <ul>
* <li>{@link #isRunning()} returns {@code false}, indicating that the
* application is shutting down.</li>
* <li>{@link #shutdown()} is triggered by the user (e.g. due to
* pressing CTRL+C)</li>
* <li>The input stream is closed.</li>
* </ul>
*/
public void start() {
try {
final @Nullable Terminal terminal = TerminalConsoleAppender.getTerminal();
if (terminal != null) {
readCommands(terminal);
} else {
readCommands(System.in);
}
} catch (IOException e) {
LogManager.getLogger("TerminalConsole").error("Failed to read console input", e);
}
}

private void readCommands(Terminal terminal) {
LineReader reader = buildReader(LineReaderBuilder.builder().terminal(terminal));
TerminalConsoleAppender.setReader(reader);

try {
String line;
while (isRunning()) {
try {
line = reader.readLine("> ");
} catch (EndOfFileException ignored) {
// Continue reading after EOT
continue;
}

if (line == null) {
break;
}

processInput(line);
}
} catch (UserInterruptException e) {
shutdown();
} finally {
TerminalConsoleAppender.setReader(null);
}
}

private void readCommands(InputStream in) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line;
while (isRunning() && (line = reader.readLine()) != null) {
processInput(line);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package net.minecraftforge.server.terminalconsole;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.AbstractLookup;
import org.apache.logging.log4j.core.lookup.StrLookup;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* A {@link StrLookup} that returns properties specific to
* {@link TerminalConsoleAppender}. The following properties are supported:
*
* <ul>
* <li>{@code ${tca:disableAnsi}}: Can be used together with
* {@code PatternLayout} to disable ANSI colors for patterns like
* {@code %highlight} or {@code %style} if ANSI colors are unsupported
* or are disabled for {@link TerminalConsoleAppender}.
*
* <p><b>Example usage:</b>
* {@code <PatternLayout ... disableAnsi="${tca:disableAnsi}">}</p></li>
* </ul>
*/
@Plugin(name = "tca", category = StrLookup.CATEGORY)
public final class TCALookup extends AbstractLookup {

/**
* Lookup key that returns if ANSI colors are unsupported/disabled.
*/
public final static String KEY_DISABLE_ANSI = "disableAnsi";

@Override
@Nullable
public String lookup(LogEvent event, String key) {
if (KEY_DISABLE_ANSI.equals(key)) {
return String.valueOf(!TerminalConsoleAppender.isAnsiSupported());
}
return null;
}

}
Loading

0 comments on commit c7f4e1d

Please sign in to comment.