Skip to content

Commit

Permalink
ScriptEngine refactoring: removed highlight() and format() methods. M…
Browse files Browse the repository at this point in the history
…oved methods

implementation in ConsoleEngineImpl.
  • Loading branch information
mattirn committed Feb 23, 2020
1 parent dc1885c commit 6b8d8bc
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 191 deletions.
171 changes: 169 additions & 2 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ public void println(Map<String, Object> options, Object object) {
String style = (String) options.getOrDefault("style", "");
int width = (int) options.get("width");
if (style.equalsIgnoreCase("JSON")) {
highlight(width, style, engine.format(options, object));
highlight(width, style, engine.toJson(object));
} else if (!style.isEmpty() && object instanceof String) {
highlight(width, style, (String) object);
} else if (object instanceof Exception) {
Expand All @@ -823,7 +823,7 @@ public void println(Map<String, Object> options, Object object) {
} else if (object instanceof Number) {
highlight(AttributedStyle.BLUE + AttributedStyle.BRIGHT, object);
} else {
for (AttributedString as : engine.highlight(options, object)) {
for (AttributedString as : highlight(options, object)) {
as.println(terminal());
}
}
Expand Down Expand Up @@ -860,6 +860,173 @@ private void highlight(int width, String style, String object) {
}
}

private List<AttributedString> highlight(Map<String, Object> options, Object obj) {
List<AttributedString> out = new ArrayList<>();
try {
out = internalHighlight(options, obj);
} catch (Exception e) {
out = internalHighlight(options, engine.convert(obj));
}
return out;
}

@SuppressWarnings("unchecked")
private List<AttributedString> internalHighlight(Map<String, Object> options, Object obj) {
List<AttributedString> out = new ArrayList<>();
int width = (int)options.getOrDefault("width", Integer.MAX_VALUE);
boolean rownum = options.containsKey("rownum");
if (obj == null) {
// do nothing
} else if (obj instanceof Map) {
out = highlightMap((Map<String, Object>)obj, width);
} else if (obj instanceof Collection<?> || obj instanceof Object[]) {
Collection<?> collection = obj instanceof Collection<?> ? (Collection<?>)obj
: Arrays.asList((Object[])obj);
if (!collection.isEmpty()) {
if (collection.size() == 1) {
Object elem = collection.iterator().next();
if (elem instanceof Map) {
out = highlightMap((Map<String, Object>)elem, width);
} else {
out.add(new AttributedString(engine.toString(obj)));
}
} else {
Object elem = collection.iterator().next();
if (elem instanceof Map) {
Map<String, Object> map = (Map<String, Object>)elem;
List<String> header = new ArrayList<>();
header.addAll(map.keySet());
List<Integer> columns = new ArrayList<>();
for (int i = 0; i < header.size(); i++) {
columns.add(header.get(i).length() + 1);
}
for (Object o : collection) {
for (int i = 0; i < header.size(); i++) {
Map<String, Object> m = (Map<String, Object>)o;
if (engine.toString(m.get(header.get(i))).length() > columns.get(i) - 1) {
columns.set(i, engine.toString(m.get(header.get(i))).length() + 1);
}
}
}
columns.add(0, 0);
toTabStops(columns, rownum);
AttributedStringBuilder asb = new AttributedStringBuilder().tabs(columns);
if (rownum) {
asb.append("\t");
}
for (int i = 0; i < header.size(); i++) {
asb.append(header.get(i), AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE + AttributedStyle.BRIGHT));
asb.append("\t");
}
out.add(truncate(asb, width));
Integer row = 0;
for (Object o : collection) {
AttributedStringBuilder asb2 = new AttributedStringBuilder().tabs(columns);
if (rownum) {
asb2.append(row.toString(), AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE + AttributedStyle.BRIGHT));
asb2.append("\t");
row++;
}
for (int i = 0; i < header.size(); i++) {
Map<String, Object> m = (Map<String, Object>)o;
asb2.append(engine.toString(m.get(header.get(i))));
asb2.append("\t");
}
out.add(asb2.subSequence(0, width));
}
} else if (elem instanceof Collection || elem instanceof Object[]) {
boolean isCollection = elem instanceof Collection;
List<Integer> columns = new ArrayList<>();
for (Object o : collection) {
List<Object> inner = new ArrayList<>();
inner.addAll(isCollection ? (Collection<?>)o : Arrays.asList((Object[])o));
for (int i = 0; i < inner.size(); i++) {
int len1 = engine.toString(inner.get(i)).length() + 1;
if (columns.size() <= i) {
columns.add(len1);
} else if (len1 > columns.get(i)) {
columns.set(i, len1);
}
}
}
toTabStops(columns, rownum);
Integer row = 0;
for (Object o : collection) {
AttributedStringBuilder asb = new AttributedStringBuilder().tabs(columns);
if (rownum) {
asb.append(row.toString(), AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE + AttributedStyle.BRIGHT));
asb.append("\t");
row++;
}
List<Object> inner = new ArrayList<>();
inner.addAll(isCollection ? (Collection<?>)o : Arrays.asList((Object[])o));
for (int i = 0; i < inner.size(); i++) {
asb.append(engine.toString(inner.get(i)));
asb.append("\t");
}
out.add(truncate(asb, width));
}
} else {
Integer row = 0;
Integer tabsize = ((Integer)collection.size()).toString().length() + 1;
for (Object o: collection) {
AttributedStringBuilder asb = new AttributedStringBuilder().tabs(tabsize);
if (rownum) {
asb.append(row.toString(), AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE + AttributedStyle.BRIGHT));
asb.append("\t");
row++;
}
asb.append(engine.toString(o));
out.add(truncate(asb, width));
}
}
}
}
} else {
out.add(new AttributedString(engine.toString(obj)));
}
return out;
}

private AttributedString truncate(AttributedStringBuilder asb, int width) {
return asb.columnLength() > width ? asb.subSequence(0, width) : asb.toAttributedString();
}

private void toTabStops(List<Integer> columns, boolean rownum) {
if (rownum) {
columns.add(0, 5);
}
for (int i = 1; i < columns.size(); i++) {
columns.set(i, columns.get(i - 1) + columns.get(i));
}
}

private List<AttributedString> highlightMap(Map<String, Object> map, int width) {
List<AttributedString> out = new ArrayList<>();
int max = map.keySet().stream().map(String::length).max(Integer::compareTo).get();
for (Map.Entry<String, Object> entry : map.entrySet()) {
AttributedStringBuilder asb = new AttributedStringBuilder().tabs(Arrays.asList(0, max + 1));
asb.append(entry.getKey(), AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE + AttributedStyle.BRIGHT));
if (map.size() == 1) {
for (String v : engine.toString(entry.getValue()).split("\\r?\\n")) {
asb.append("\t");
asb.append(v, AttributedStyle.DEFAULT.foreground(AttributedStyle.YELLOW));
out.add(truncate(asb, width));
asb = new AttributedStringBuilder().tabs(Arrays.asList(0, max + 1));
}
} else {
String v = engine.toString(entry.getValue());
if (v.contains("\n")) {
v = Arrays.asList(v.split("\\r?\\n")).toString();
}
asb.append("\t");
asb.append(v, AttributedStyle.DEFAULT.foreground(AttributedStyle.YELLOW));
out.add(truncate(asb, width));
}
}
return out;
}

private Object show(Builtins.CommandInput input) {
final String[] usage = {
"show - list console variables",
Expand Down
3 changes: 3 additions & 0 deletions groovy/src/main/groovy/org/jline/groovy/Utils.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class Utils {
}

static Object convert(Object object) {
if (object instanceof String) {
return object;
}
def slurper = new JsonSlurper()
slurper.parseText(JsonOutput.toJson(object))
}
Expand Down

0 comments on commit 6b8d8bc

Please sign in to comment.