diff --git a/console/src/main/java/org/jline/console/impl/DefaultPrinter.java b/console/src/main/java/org/jline/console/impl/DefaultPrinter.java index d95d45f45..a5556b639 100644 --- a/console/src/main/java/org/jline/console/impl/DefaultPrinter.java +++ b/console/src/main/java/org/jline/console/impl/DefaultPrinter.java @@ -58,6 +58,10 @@ public class DefaultPrinter extends JlineCommandRegistry implements Printer { private ConfigurationPath configPath; private StyleResolver prntStyle; + public DefaultPrinter(ConfigurationPath configPath) { + this(null, configPath); + } + public DefaultPrinter(ScriptEngine engine, ConfigurationPath configPath) { this.engine = engine; this.configPath = configPath; @@ -69,7 +73,9 @@ public void println(Object object) { } @Override - public void println(Map options, Object object) { + public void println(Map optionsIn, Object object) { + Map options = new HashMap<>(); + options.putAll(optionsIn); for (Map.Entry entry : defaultPrntOptions(options.containsKey(Printer.SKIP_DEFAULT_OPTIONS)).entrySet()) { options.putIfAbsent(entry.getKey(), entry.getValue()); @@ -170,8 +176,10 @@ public Exception prntCommand(CommandInput input) { private List variableReferences() { List out = new ArrayList<>(); - for (String v : engine.find().keySet()) { - out.add("$" + v); + if (engine != null) { + for (String v : engine.find().keySet()) { + out.add("$" + v); + } } return out; } @@ -230,7 +238,7 @@ private void manageBooleanOptions(Map options) { @SuppressWarnings("unchecked") private Map defaultPrntOptions(boolean skipDefault) { Map out = new HashMap<>(); - if (!skipDefault && engine.hasVariable(VAR_PRNT_OPTIONS)) { + if (engine != null && !skipDefault && engine.hasVariable(VAR_PRNT_OPTIONS)) { out.putAll((Map)engine.get(VAR_PRNT_OPTIONS)); out.remove(Printer.SKIP_DEFAULT_OPTIONS); manageBooleanOptions(out); @@ -240,6 +248,11 @@ private Map defaultPrntOptions(boolean skipDefault) { out.putIfAbsent(Printer.INDENTION, PRNT_INDENTION); out.putIfAbsent(Printer.COLUMNS_OUT, new ArrayList()); out.putIfAbsent(Printer.COLUMNS_IN, new ArrayList()); + if (engine == null) { + out.remove(Printer.OBJECT_TO_MAP); + out.remove(Printer.OBJECT_TO_STRING); + out.remove(Printer.HIGHLIGHT_VALUE); + } return out; } @@ -273,6 +286,9 @@ private void internalPrintln(Map options, Object object) { if (!style.isEmpty() && object instanceof String) { highlightAndPrint(width, style, (String) object); } else if (style.equalsIgnoreCase("JSON")) { + if (engine == null) { + throw new IllegalArgumentException("JSON style not supported!"); + } highlightAndPrint(width, style, engine.toJson(object)); } else if (options.containsKey(Printer.SKIP_DEFAULT_OPTIONS)) { highlightAndPrint(options, object); @@ -325,7 +341,7 @@ private SyntaxHighlighter valueHighlighter(String style) { out = SyntaxHighlighter.build(style); } else { Path nanorc = configPath != null ? configPath.getConfig("jnanorc") : null; - if (engine.hasVariable(VAR_NANORC)) { + if (engine != null && engine.hasVariable(VAR_NANORC)) { nanorc = Paths.get((String)engine.get(VAR_NANORC)); } if (nanorc == null) { @@ -487,19 +503,24 @@ private Map objectToMap(Map options, Object obj) @SuppressWarnings("unchecked") private String objectToString(Map options, Object obj) { + String out = "null"; if (obj != null) { Map, Object> toString = options.containsKey(Printer.OBJECT_TO_STRING) ? (Map, Object>)options.get(Printer.OBJECT_TO_STRING) : new HashMap<>(); if (toString.containsKey(obj.getClass())) { - return (String) engine.execute(toString.get(obj.getClass()), obj); + out = (String) engine.execute(toString.get(obj.getClass()), obj); } else if (objectToString.containsKey(obj.getClass())) { - return objectToString.get(obj.getClass()).apply(obj); + out = objectToString.get(obj.getClass()).apply(obj); } else if (obj instanceof Class) { - return ((Class) obj).getName(); + out = ((Class) obj).getName(); + } else if (engine != null) { + out = engine.toString(obj); + } else { + out = obj.toString(); } } - return engine.toString(obj); + return out; } private AttributedString highlightMapValue(Map options, String key, Map map) { @@ -774,7 +795,7 @@ private void highlightAndPrint(Map options, Object obj) { for (Object o : collection) { List inner = objectToList(o); for (int i = 0; i < inner.size(); i++) { - int len1 = engine.toString(inner.get(i)).length() + 1; + int len1 = objectToString(options, inner.get(i)).length() + 1; if (columns.size() <= i) { columns.add(len1); } else if (len1 > columns.get(i)) { @@ -868,7 +889,7 @@ private boolean simpleObject(Object obj) { } private boolean canConvert(Object obj) { - if (obj == null || obj instanceof Class || obj instanceof Map || simpleObject(obj) || collectionObject(obj)) { + if (engine == null || obj == null || obj instanceof Class || obj instanceof Map || simpleObject(obj) || collectionObject(obj)) { return false; } return true; diff --git a/console/src/main/java/org/jline/console/impl/SystemRegistryImpl.java b/console/src/main/java/org/jline/console/impl/SystemRegistryImpl.java index 32399e59b..3142d515e 100644 --- a/console/src/main/java/org/jline/console/impl/SystemRegistryImpl.java +++ b/console/src/main/java/org/jline/console/impl/SystemRegistryImpl.java @@ -1334,7 +1334,7 @@ private void printCommands(Collection commands, int max) { } private String doCommandInfo(List info) { - return info.size() > 0 ? info.get(0) : " "; + return info != null && info.size() > 0 ? info.get(0) : " "; } private boolean isInTopics(List args, String name) { diff --git a/console/src/test/java/org/jline/example/Console.java b/console/src/test/java/org/jline/example/Console.java index 949c9130a..6d14e0bd0 100644 --- a/console/src/test/java/org/jline/example/Console.java +++ b/console/src/test/java/org/jline/example/Console.java @@ -18,11 +18,13 @@ import org.jline.console.CommandInput; import org.jline.console.CommandMethods; import org.jline.console.CommandRegistry; +import org.jline.console.Printer; import org.jline.widget.AutopairWidgets; import org.jline.widget.AutosuggestionWidgets; import org.jline.widget.TailTipWidgets; import org.jline.widget.TailTipWidgets.TipType; import org.jline.console.impl.Builtins; +import org.jline.console.impl.DefaultPrinter; import org.jline.console.impl.SystemRegistryImpl; import org.jline.keymap.KeyMap; import org.jline.reader.*; @@ -90,8 +92,11 @@ private static class ExampleCommands implements CommandRegistry { private final Map> commandInfo = new HashMap<>(); private Map aliasCommand = new HashMap<>(); private Exception exception; + private Printer printer; - public ExampleCommands() { + public ExampleCommands(Printer printer) { + this.printer = printer; + commandExecute.put("testprint", new CommandMethods(this::testprint, this::defaultCompleter)); commandExecute.put("testkey", new CommandMethods(this::testkey, this::defaultCompleter)); commandExecute.put("clear", new CommandMethods(this::clear, this::defaultCompleter)); commandExecute.put("autopair", new CommandMethods(this::autopair, this::defaultCompleter)); @@ -174,6 +179,34 @@ public CmdDesc commandDescription(String command) { return new CmdDesc(false); } + private Map fillMap(String name, Integer age, String country, String town) { + Map out = new HashMap<>(); + Map address = new HashMap<>(); + address.put("country", country); + address.put("town", town); + out.put("name", name); + out.put("age", age); + out.put("address", address); + return out; + } + + private void testprint(CommandInput input) { + List> data = new ArrayList<>(); + data.add(fillMap("heikki", 10, "finland", "helsinki")); + data.add(fillMap("pietro", 11, "italy", "milano")); + data.add(fillMap("john", 12, "england", "london")); + printer.println(data); + Map options = new HashMap<>(); + options.put(Printer.STRUCT_ON_TABLE, true); + options.put(Printer.VALUE_STYLE, "classpath:/org/jline/example/gron.nanorc"); + printer.println(options,data); + options.clear(); + options.put(Printer.COLUMNS, Arrays.asList("name", "age", "address.country", "address.town")); + options.put(Printer.SHORT_NAMES, true); + options.put(Printer.VALUE_STYLE, "classpath:/org/jline/example/gron.nanorc"); + printer.println(options,data); + } + private void testkey(CommandInput input) { try { terminal().writer().write("Input the key event(Enter to complete): "); @@ -313,7 +346,8 @@ public void complete(LineReader reader, ParsedLine line, List candida builtins.rename(Builtins.Command.TTOP, "top"); builtins.alias("zle", "widget"); builtins.alias("bindkey", "keymap"); - ExampleCommands exampleCommands = new ExampleCommands(); + DefaultPrinter printer = new DefaultPrinter(null); + ExampleCommands exampleCommands = new ExampleCommands(printer); SystemRegistryImpl masterRegistry = new SystemRegistryImpl(parser, terminal, Console::workDir, null); masterRegistry.setCommandRegistries(exampleCommands, builtins); masterRegistry.addCompleter(completer); diff --git a/console/src/test/resources/org/jline/example/gron.nanorc b/console/src/test/resources/org/jline/example/gron.nanorc new file mode 100644 index 000000000..c9b8110ef --- /dev/null +++ b/console/src/test/resources/org/jline/example/gron.nanorc @@ -0,0 +1,12 @@ +syntax "GRON" "\.gron$" +header "^\[$" + +color brightblue "\<[-]?[0-9]*([Ee][+-]?[0-9]+)?\>" "\<[-]?[0](\.[0-9]+)?\>" +color yellow ""(\\.|[^"])*"|'(\\.|[^'])*'|[a-zA-Z]+[a-zA-Z0-9]*" +color cyan "\" +color brightcyan "\<(true|false)\>" +color brightyellow "\"(\\"|[^"])*\"\s*:" "'(\'|[^'])*'\s*:" "(\[|,)\s*[a-zA-Z0-9]*\s*:" +color white "(:|\[|,|\])" +color magenta "\\u[0-9a-fA-F]{4}|\\[bfnrt'"/\\]" +color ,green "[[:space:]]+$" +color ,red " + +| + +" \ No newline at end of file