Skip to content

Commit

Permalink
Named styles and colors can be used in variables LS_COLORS, HELP_COLO…
Browse files Browse the repository at this point in the history
…RS and PRNT_COLORS
  • Loading branch information
mattirn committed Dec 28, 2020
1 parent e1c75ce commit a27bcd1
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 72 deletions.
70 changes: 4 additions & 66 deletions builtins/src/main/java/org/jline/builtins/Nano.java
Original file line number Diff line number Diff line change
Expand Up @@ -1655,29 +1655,12 @@ public static RuleType evalRuleType(List<String> colorCfg) {

private static class NanorcParser {
private static final String DEFAULT_SYNTAX = "default";
private static final List<String> JLINE_NAMED_STYLES = Arrays.asList("blink", "bold", "conceal", "crossed-out"
, "crossedout", "faint", "hidden", "inverse", "inverse-neg", "inverseneg", "italic", "underline");
private static final List<String> COLORS_8 = Arrays.asList("white", "black", "red", "blue", "green", "yellow", "magenta", "cyan");
// https://github.com/lhmouse/nano-win/commit/a7aab18dfeef8a0e8073d5fa420677dc8fe548da
private static final Map<String,Integer> COLORS_NANO = new HashMap<>();
static {
COLORS_NANO.put("pink", 204);
COLORS_NANO.put("purple", 163);
COLORS_NANO.put("mauve", 134);
COLORS_NANO.put("lagoon", 38);
COLORS_NANO.put("mint", 48);
COLORS_NANO.put("lime", 148);
COLORS_NANO.put("peach", 215);
COLORS_NANO.put("orange", 208);
COLORS_NANO.put("latte", 137);
}
private final String name;
private final String target;
private final List<HighlightRule> highlightRules = new ArrayList<>();
private final BufferedReader reader;
private boolean matches = false;
private String syntaxName = "unknown";
private final Map<String,String[]> styleSpecs = new HashMap<>();

public NanorcParser(Path file, String name, String target) throws IOException {
this(new Source.PathSource(file, null).read(), name, target);
Expand Down Expand Up @@ -1758,56 +1741,11 @@ public boolean isDefault() {
return syntaxName.equals(DEFAULT_SYNTAX);
}

private String getStyle(String reference) {
StringBuilder out = new StringBuilder();
boolean first = true;
boolean fg = true;
for (String s : styleSpecs.get(reference)) {
if (s.trim().isEmpty()) {
fg = false;
continue;
}
if (!first) {
out.append(",");
}
if (JLINE_NAMED_STYLES.contains(s)) {
out.append(s);
} else if (COLORS_8.contains(s) || COLORS_NANO.containsKey(s) || s.startsWith("light")
|| s.startsWith("bright") || s.startsWith("~") || s.startsWith("!") || s.matches("\\d+")
|| s.equals("normal") || s.equals("default")) {
if (s.matches("\\d+") || COLORS_NANO.containsKey(s)) {
if (fg) {
out.append("38;5;");
} else {
out.append("48;5;");
}
out.append(s.matches("\\d+") ? s : COLORS_NANO.get(s).toString());
} else {
if (fg) {
out.append("fg:");
} else {
out.append("bg:");
}
if (COLORS_8.contains(s) || s.startsWith("~") || s.startsWith("!") || s.startsWith("bright-")) {
out.append(s);
} else if (s.startsWith("light")) {
out.append("!").append(s.substring(5));
} else if (s.startsWith("bright")) {
out.append("!").append(s.substring(6));
} else {
out.append("default");
}
}
fg = false;
}
first = false;
}
return out.toString();
}

private void addHighlightRule(String reference, List<String> parts, boolean caseInsensitive) {
styleSpecs.put(reference, parts.get(1).split(","));
AttributedStyle style = new StyleResolver(this::getStyle).resolve("." + reference);
Map<String,String> spec = new HashMap<>();
spec.put(reference, parts.get(1));
Styles.StyleCompiler sh = new Styles.StyleCompiler(spec, true);
AttributedStyle style = new StyleResolver(sh::getStyle).resolve("." + reference);

if (HighlightRule.evalRuleType(parts) == HighlightRule.RuleType.PATTERN) {
for (int i = 2; i < parts.size(); i++) {
Expand Down
100 changes: 94 additions & 6 deletions builtins/src/main/java/org/jline/builtins/Styles.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
package org.jline.builtins;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

Expand All @@ -23,8 +25,9 @@ public class Styles {
private static final String PRNT_COLORS = "PRNT_COLORS";

private static final String KEY = "([a-z]{2}|\\*\\.[a-zA-Z0-9]+)";
private static final String VALUE = "[0-9]*(;[0-9]+){0,2}";
private static final String ANSI_STYLE_PATTERN = KEY + "=" + VALUE + "(:" + KEY + "=" + VALUE + ")*(:|)";
private static final String VALUE = "[!~]?[a-zA-Z0-9]+[a-z0-9-;]*";
private static final String VALUES = VALUE + "(," + VALUE + ")*";
private static final String STYLE_PATTERN = KEY + "=" + VALUES + "(:" + KEY + "=" + VALUES + ")*(:|)";

public static StyleResolver lsStyle() {
return style(LS_COLORS, DEFAULT_LS_COLORS);
Expand All @@ -39,7 +42,7 @@ public static StyleResolver prntStyle() {
}

public static boolean isAnsiStylePattern(String style) {
return style.matches(ANSI_STYLE_PATTERN);
return style.matches(STYLE_PATTERN);
}

private static StyleResolver style(String name, String defStyle) {
Expand All @@ -57,15 +60,16 @@ private static String consoleOption(String name) {
.getDeclaredMethod("get").invoke(null);
if (cog != null) {
out = (String)cog.consoleOption(name);
if (out != null && !out.matches(ANSI_STYLE_PATTERN)) {
if (out != null && !out.matches(STYLE_PATTERN)) {
out = null;
}
}
} catch (Exception e) {
// ignore
}
if (out == null) {
out = System.getenv(name);
if (out != null && !out.matches(ANSI_STYLE_PATTERN)) {
if (out != null && !out.matches(STYLE_PATTERN)) {
out = null;
}
}
Expand All @@ -76,6 +80,90 @@ private static StyleResolver style(String style) {
Map<String, String> colors = Arrays.stream(style.split(":"))
.collect(Collectors.toMap(s -> s.substring(0, s.indexOf('=')),
s -> s.substring(s.indexOf('=') + 1)));
return new StyleResolver(colors::get);
return new StyleResolver(new StyleCompiler(colors)::getStyle);
}

protected static class StyleCompiler {
private static final String ANSI_VALUE = "[0-9]*(;[0-9]+){0,2}";
private static final List<String> JLINE_NAMED_STYLES = Arrays.asList("blink", "bold", "conceal", "crossed-out"
, "crossedout", "faint", "hidden", "inverse", "inverse-neg", "inverseneg", "italic", "underline");
private static final List<String> COLORS_8 = Arrays.asList("white", "black", "red", "blue", "green", "yellow", "magenta", "cyan");
// https://github.com/lhmouse/nano-win/commit/a7aab18dfeef8a0e8073d5fa420677dc8fe548da
private static final Map<String,Integer> COLORS_NANO = new HashMap<>();
static {
COLORS_NANO.put("pink", 204);
COLORS_NANO.put("purple", 163);
COLORS_NANO.put("mauve", 134);
COLORS_NANO.put("lagoon", 38);
COLORS_NANO.put("mint", 48);
COLORS_NANO.put("lime", 148);
COLORS_NANO.put("peach", 215);
COLORS_NANO.put("orange", 208);
COLORS_NANO.put("latte", 137);
}
private final Map<String,String> colors;
private final boolean nanoStyle;

public StyleCompiler(Map<String,String> colors) {
this(colors, false);
}
public StyleCompiler(Map<String,String> colors, boolean nanoStyle) {
this.colors = colors;
this.nanoStyle = nanoStyle;
}

public String getStyle(String reference) {
if (!colors.containsKey(reference)) {
throw new IllegalStateException();
}
String rawStyle = colors.get(reference);
if (!nanoStyle && rawStyle.matches(ANSI_VALUE)) {
return rawStyle;
}
StringBuilder out = new StringBuilder();
boolean first = true;
boolean fg = true;
for (String s : rawStyle.split(",")) {
if (s.trim().isEmpty()) {
fg = false;
continue;
}
if (!first) {
out.append(",");
}
if (JLINE_NAMED_STYLES.contains(s)) {
out.append(s);
} else if (COLORS_8.contains(s) || COLORS_NANO.containsKey(s) || s.startsWith("light")
|| s.startsWith("bright") || s.startsWith("~") || s.startsWith("!") || s.matches("\\d+")
|| s.equals("normal") || s.equals("default")) {
if (s.matches("\\d+") || COLORS_NANO.containsKey(s)) {
if (fg) {
out.append("38;5;");
} else {
out.append("48;5;");
}
out.append(s.matches("\\d+") ? s : COLORS_NANO.get(s).toString());
} else {
if (fg) {
out.append("fg:");
} else {
out.append("bg:");
}
if (COLORS_8.contains(s) || s.startsWith("~") || s.startsWith("!") || s.startsWith("bright-")) {
out.append(s);
} else if (s.startsWith("light")) {
out.append("!").append(s.substring(5));
} else if (s.startsWith("bright")) {
out.append("!").append(s.substring(6));
} else {
out.append("default");
}
}
fg = false;
}
first = false;
}
return out.toString();
}
}
}

0 comments on commit a27bcd1

Please sign in to comment.