Skip to content

Commit

Permalink
NanorcParser: add nano color name extensions and use StyleResolver
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Dec 27, 2020
1 parent 785c06a commit e1c75ce
Showing 1 changed file with 72 additions and 98 deletions.
170 changes: 72 additions & 98 deletions builtins/src/main/java/org/jline/builtins/Nano.java
Expand Up @@ -29,17 +29,8 @@
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
Expand All @@ -56,11 +47,7 @@
import org.jline.terminal.Terminal;
import org.jline.terminal.Terminal.Signal;
import org.jline.terminal.Terminal.SignalHandler;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStringBuilder;
import org.jline.utils.AttributedStyle;
import org.jline.utils.Display;
import org.jline.utils.Status;
import org.jline.utils.*;
import org.jline.utils.InfoCmp.Capability;
import org.mozilla.universalchardet.UniversalDetector;

Expand Down Expand Up @@ -1668,12 +1655,29 @@ 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;
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 All @@ -1686,8 +1690,10 @@ public NanorcParser(InputStream in, String name, String target) {
}

public void parse() throws IOException {
String line = reader.readLine();
while (line != null) {
String line;
int idx = 0;
while ((line = reader.readLine()) != null) {
idx++;
line = line.trim();
if (line.length() > 0 && !line.startsWith("#")) {
line = line.replaceAll("\\\\<", "\\\\b")
Expand Down Expand Up @@ -1731,12 +1737,11 @@ public void parse() throws IOException {
matches = true;
}
} else if (parts.get(0).equals("color")) {
addHighlightRule(parts, false);
addHighlightRule(syntaxName + idx, parts, false);
} else if (parts.get(0).equals("icolor")) {
addHighlightRule(parts, true);
addHighlightRule(syntaxName + idx, parts, true);
}
}
line = reader.readLine();
}
reader.close();
}
Expand All @@ -1753,87 +1758,56 @@ public boolean isDefault() {
return syntaxName.equals(DEFAULT_SYNTAX);
}

private Integer toColor(String styleString) {
Integer out = null;
if (styleString.length() > 0) {
out = 0;
if (styleString.startsWith("bright")) {
out = AttributedStyle.BRIGHT;
styleString = styleString.substring(6);
}
if (styleString.equals("white")) {
out += AttributedStyle.WHITE;
} else if (styleString.equals("black")) {
out += AttributedStyle.BLACK;
} else if (styleString.equals("red")) {
out += AttributedStyle.RED;
} else if (styleString.equals("blue")) {
out += AttributedStyle.BLUE;
} else if (styleString.equals("green")) {
out += AttributedStyle.GREEN;
} else if (styleString.equals("yellow")) {
out += AttributedStyle.YELLOW;
} else if (styleString.equals("magenta")) {
out += AttributedStyle.MAGENTA;
} else if (styleString.equals("cyan")) {
out += AttributedStyle.CYAN;
} else if (styleString.matches("\\d+")) {
out = Integer.parseInt(styleString);
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;
}

private AttributedStyle setStyle(String name, AttributedStyle style) {
AttributedStyle out = style;
switch (name) {
case "blink":
out = style.blink();
break;
case "bold":
out = style.bold();
break;
case "conceal":
out = style.conceal();
break;
case "faint":
out = style.faint();
break;
case "hidden":
out = style.hidden();
break;
case "inverse":
out = style.inverse();
break;
case "italic":
out = style.italic();
break;
case "underline":
out = style.underline();
break;
default:
}
return out;
return out.toString();
}

private void addHighlightRule(List<String> parts, boolean caseInsensitive) {
AttributedStyle style = AttributedStyle.DEFAULT.foreground(AttributedStyle.BLACK + AttributedStyle.BRIGHT);
String[] styleStrings = parts.get(1).split(",");
List<String> styles = Arrays.asList("blink", "bold", "conceal", "faint", "hidden", "inverse", "italic", "underline");
int colorStart = 0;
// GNU nano version >= v5 support styles: bold and italic, rest jline extension
while (styles.contains(styleStrings[colorStart])) {
style = setStyle(styleStrings[colorStart], style);
colorStart++;
}
Integer fcolor = toColor(styleStrings[colorStart]);
Integer bcolor = styleStrings.length > 1 + colorStart ? toColor(styleStrings[colorStart + 1]) : null;
if (fcolor != null) {
style = style.foreground(fcolor);
}
if (bcolor != null) {
style = style.background(bcolor);
}
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);

if (HighlightRule.evalRuleType(parts) == HighlightRule.RuleType.PATTERN) {
for (int i = 2; i < parts.size(); i++) {
Expand Down

0 comments on commit e1c75ce

Please sign in to comment.