Skip to content

Commit

Permalink
prnt command customization
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Mar 13, 2020
1 parent 02c7f67 commit f30e34b
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 22 deletions.
144 changes: 122 additions & 22 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -65,6 +66,9 @@ public enum Command {SHOW
private Map<String,Command> nameCommand = new HashMap<>();
private Map<String,String> aliasCommand = new HashMap<>();
private final Map<Command,CommandMethods> commandExecute = new HashMap<>();
private Map<Class<?>, Function<Object, Map<String,Object>>> objectToMap = new HashMap<>();
private Map<Class<?>, Function<Object, String>> objectToString = new HashMap<>();
private Map<String, Function<Object, AttributedString>> highlightValue = new HashMap<>();
private Exception exception;
private SystemRegistry systemRegistry;
private String scriptExtension = "jline";
Expand Down Expand Up @@ -103,6 +107,18 @@ public ConsoleEngineImpl(ScriptEngine engine
}
}

public void setObjectToMap(Map<Class<?>, Function<Object, Map<String,Object>>> objectToMap) {
this.objectToMap = objectToMap;
}

public void setObjectToString(Map<Class<?>, Function<Object, String>> objectToString) {
this.objectToString = objectToString;
}

public void setHighlightValue(Map<String, Function<Object, AttributedString>> highlightValue) {
this.highlightValue = highlightValue;
}

@Override
public void setLineReader(LineReader reader) {
this.reader = reader;
Expand Down Expand Up @@ -282,7 +298,7 @@ public Object[] expandParameters(String[] args) throws Exception {
}

private String expandToList(String[] args) {
return expandToList(Arrays.asList(args).subList(1, args.length));
return expandToList(Arrays.asList(args));
}

@Override
Expand Down Expand Up @@ -987,13 +1003,87 @@ private boolean hasMatch(List<String> regexes, String value) {
return false;
}

private String addPadding(String str, int width) {
StringBuilder sb = new StringBuilder();
for (int i = str.length(); i < width; i++) {
private AttributedString addPadding(String str, int width) {
return addPadding(new AttributedString(str), width);
}

private AttributedString addPadding(AttributedString str, int width) {
AttributedStringBuilder sb = new AttributedStringBuilder();
for (int i = str.columnLength(); i < width; i++) {
sb.append(" ");
}
sb.append(str);
return sb.toString();
return sb.toAttributedString();
}

private String columnValue(String value) {
return value.replaceAll("\r","CR").replaceAll("\n", "LF");
}

@SuppressWarnings("unchecked")
private Map<String,Object> objectToMap(Map<String, Object> options, Object obj) {
Map<Class<?>, Object> toMap = options.containsKey("objectToMap") ? (Map<Class<?>, Object>)options.get("objectToMap")
: new HashMap<>();;
if (toMap.containsKey(obj.getClass())) {
return (Map<String,Object>)engine.execute(toMap.get(obj.getClass()), obj);
} else if (objectToMap.containsKey(obj.getClass())) {
return objectToMap.get(obj.getClass()).apply(obj);
}
return engine.toMap(obj);
}

@SuppressWarnings("unchecked")
private String objectToString(Map<String, Object> options, Object obj) {
Map<Class<?>, Object> toString = options.containsKey("objectToString") ? (Map<Class<?>, Object>)options.get("objectToString")
: new HashMap<>();;
if (toString.containsKey(obj.getClass())) {
return (String)engine.execute(toString.get(obj.getClass()), obj);
} else if (objectToString.containsKey(obj.getClass())) {
return objectToString.get(obj.getClass()).apply(obj);
}
return engine.toString(obj);
}

@SuppressWarnings("unchecked")
private AttributedString highlightValue(Map<String, Object> options, String column, Object obj) {
AttributedString out = new AttributedString("");
Object raw = stringDemanded(options, obj) ? objectToString(options, obj) : obj;
boolean done = false;
if (column != null) {
Map<String, Object> hv = options.containsKey("highlightValue") ? (Map<String, Object>)options.get("highlightValue")
: new HashMap<>();;
for (Map.Entry<String,Object> entry : hv.entrySet()) {
if (column.matches(entry.getKey())) {
out = (AttributedString)engine.execute(hv.get(entry.getKey()), raw);
done = true;
break;
}
}
if (!done) {
for (Map.Entry<String,Function<Object,AttributedString>> entry : highlightValue.entrySet()) {
if (column.matches(entry.getKey())) {
out = highlightValue.get(entry.getKey()).apply(raw);
done = true;
break;
}
}
}
}
if (!done) {
if (raw instanceof String) {
out = new AttributedString(columnValue((String)raw));
} else {
out = new AttributedString(columnValue(objectToString(options, raw)));
}
}
return out;
}

@SuppressWarnings("unchecked")
private boolean stringDemanded(Map<String, Object> options, Object obj) {
Map<Class<?>, Object> toString = options.containsKey("objectToString") ? (Map<Class<?>, Object>)options.get("objectToString")
: new HashMap<>();;
return toString.containsKey(obj.getClass()) || objectToString.containsKey(obj.getClass());
}

@SuppressWarnings("unchecked")
Expand All @@ -1013,19 +1103,20 @@ private List<AttributedString> highlight(Map<String, Object> options, Object obj
Object elem = collection.iterator().next();
if (elem instanceof Map) {
out = highlightMap(keysToString((Map<Object, Object>)elem), width);
} else if (canConvert(elem)){
out = highlightMap(engine.toMap(elem), width);
} else if (canConvert(elem) && !stringDemanded(options, obj)){
out = highlightMap(objectToMap(options, elem), width);
} else {
out.add(new AttributedString(engine.toString(obj)));
out.add(new AttributedString(objectToString(options, obj)));
}
} else {
Object elem = collection.iterator().next();
boolean convert = canConvert(elem);
if (elem instanceof Map || convert) {
Map<String, Object> map = convert ? engine.toMap(elem): keysToString((Map<Object, Object>)elem);
Map<String, Object> map = convert ? objectToMap(options, elem) : keysToString((Map<Object, Object>)elem);
List<String> _header = null;
List<String> columnsIn = optionList("columnsIn", options);
List<String> columnsOut = optionList("columnsOut", options);
List<String> columnsOut = !options.containsKey("all") ? optionList("columnsOut", options)
: new ArrayList<>();
if (options.containsKey("columns")) {
_header = (List<String>)options.get("columns");
} else {
Expand All @@ -1035,6 +1126,7 @@ private List<AttributedString> highlight(Map<String, Object> options, Object obj
}
List<String> header = new ArrayList<>();
List<Integer> columns = new ArrayList<>();
int headerWidth = 0;
for (int i = 0; i < _header.size(); i++) {
if (!map.containsKey(_header.get(i).split("\\.")[0])) {
continue;
Expand All @@ -1049,12 +1141,16 @@ private List<AttributedString> highlight(Map<String, Object> options, Object obj
}
header.add(_header.get(i));
columns.add(_header.get(i).length() + 1);
headerWidth += _header.get(i).length() + 1;
if (headerWidth > width) {
break;
}
}
for (Object o : collection) {
for (int i = 0; i < header.size(); i++) {
Map<String, Object> m = convert ? engine.toMap(o) : keysToString((Map<Object, Object>)o);
Map<String, Object> m = convert ? objectToMap(options, o) : keysToString((Map<Object, Object>)o);
if (engine.toString(m.get(header.get(i))).length() > columns.get(i) - 1) {
columns.set(i, engine.toString(mapValue(header.get(i), m)).length() + 1);
columns.set(i, highlightValue(options, header.get(i), mapValue(header.get(i), m)).columnLength() + 1);
}
}
}
Expand All @@ -1080,9 +1176,9 @@ private List<AttributedString> highlight(Map<String, Object> options, Object obj
row++;
}
for (int i = 0; i < header.size(); i++) {
Map<String, Object> m = convert ? engine.toMap(o) : keysToString((Map<Object, Object>)o);
String v = engine.toString(mapValue(header.get(i), m));
if (isNumber(v)) {
Map<String, Object> m = convert ? objectToMap(options, o) : keysToString((Map<Object, Object>)o);
AttributedString v = highlightValue(options, header.get(i), mapValue(header.get(i), m));
if (isNumber(v.toString())) {
v = addPadding(v, columns.get(firstColumn + i + 1) - columns.get(firstColumn + i) - 1);
}
asb2.append(v);
Expand Down Expand Up @@ -1118,8 +1214,8 @@ private List<AttributedString> highlight(Map<String, Object> options, Object obj
List<Object> inner = new ArrayList<>();
inner.addAll(isCollection ? (Collection<?>)o : Arrays.asList((Object[])o));
for (int i = 0; i < inner.size(); i++) {
String v = engine.toString(inner.get(i));
if (isNumber(v)) {
AttributedString v = highlightValue(options, null, inner.get(i));
if (isNumber(v.toString())) {
v = addPadding(v, columns.get(firstColumn + i + 1) - columns.get(firstColumn + i) - 1);
}
asb.append(v);
Expand All @@ -1137,16 +1233,16 @@ private List<AttributedString> highlight(Map<String, Object> options, Object obj
asb.append("\t");
row++;
}
asb.append(engine.toString(o));
asb.append(objectToString(options, o));
out.add(truncate(asb, width));
}
}
}
}
} else if (canConvert(obj)) {
out = highlightMap(engine.toMap(obj), width);
} else if (canConvert(obj) && !stringDemanded(options, obj)) {
out = highlightMap(objectToMap(options, obj), width);
} else {
out.add(new AttributedString(engine.toString(obj)));
out.add(new AttributedString(objectToString(options, obj)));
}
return out;
}
Expand Down Expand Up @@ -1240,7 +1336,8 @@ private Object prnt(Builtins.CommandInput input) {
"prnt - print object",
"Usage: prnt [OPTIONS] object",
" -? --help Displays command help",
" --columns=COLUMNS,... Display given columns on table",
" -a --all Ignore columnsOut configuration",
" -c --columns=COLUMNS,... Display given columns on table",
" --oneRowTable Display one row data on table",
" -r --rownum Display table row numbers",
" --structsOnTable Display structs and lists on table",
Expand Down Expand Up @@ -1271,6 +1368,9 @@ private Object prnt(Builtins.CommandInput input) {
if (opt.isSet("columns")) {
options.put("columns", Arrays.asList(opt.get("columns").split(",")));
}
if (opt.isSet("all")) {
options.put("all", true);
}
options.put("exception", "stack");
List<Object> args = opt.argObjects();
if (args.size() > 0) {
Expand Down
39 changes: 39 additions & 0 deletions demo/src/main/scripts/init.jline
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,45 @@ CONSOLE_OPTIONS = [:]
CONSOLE_OPTIONS.trace = 1
CONSOLE_OPTIONS.splitOutput = true
#
# customize prnt command
#
def _number2date(number){
def out = null
try {
out = number instanceof Long ? new Date(number) : number
} catch (Exception e) {
out = number
}
new org.jline.utils.AttributedString(out.toString())
}

def _reader2map(reader){
out = [:]
out['othersGroupName'] = reader.othersGroupName
out['keyMap'] = reader.keyMap
out['autosuggestion'] = reader.autosuggestion
out['terminalDumb'] = reader.terminalDumb
out
}

def _reader2string(reader){
out = "["
out += 'othersGroupName:' + reader.othersGroupName + ', '
out += 'keyMap:' + reader.keyMap + ', '
out += 'autosuggestion:' + reader.autosuggestion + ', '
out += 'terminalDumb:' + reader.terminalDumb
out += ']'
out
}

PRNT_OPTIONS = [:]
PRNT_OPTIONS['objectToMap'] = [:]
PRNT_OPTIONS['objectToString'] = [:]
PRNT_OPTIONS['highlightValue'] = [:]
PRNT_OPTIONS['objectToMap'].put(org.jline.reader.impl.LineReaderImpl, _reader2map)
PRNT_OPTIONS['objectToString'].put(org.jline.reader.impl.LineReaderImpl, _reader2string)
PRNT_OPTIONS['highlightValue'].put('time.*', _number2date)
#
# custom Groovy pipes
#
pipe --delete *
Expand Down

0 comments on commit f30e34b

Please sign in to comment.