# HG changeset patch # User rfield # Date 1476993191 25200 # Node ID cb3d04878117012f8a6a61a49064e07e1b6cd720 # Parent 3f9c491b05aa6faa8023db8fda44486ccb890c2b 8163840: jshell tool: provide way to display configuration settings Reviewed-by: jlahoda diff -r 3f9c491b05aa -r cb3d04878117 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Thu Oct 20 12:53:11 2016 -0700 @@ -30,7 +30,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Stream; import static java.util.stream.Collectors.toList; /** @@ -78,7 +77,12 @@ while (true) { nextToken(); if (sval != null && !isQuoted() && sval.startsWith("-")) { - foundOption(sval); + // allow POSIX getopt() option format, + // to be consistent with command-line + String opt = sval.startsWith("--") + ? sval.substring(1) + : sval; + foundOption(opt); } else { break; } @@ -104,28 +108,13 @@ } } - String[] next(String... strings) { - return next(Arrays.stream(strings)); - } - - String[] next(Stream stream) { - next(); - if (sval == null) { - return null; - } - String[] matches = stream - .filter(s -> s.startsWith(sval)) - .toArray(size -> new String[size]); - return matches; - } - /** * Set the allowed options. Must be called before any options would be read * and before calling any of the option functionality below. */ void allowedOptions(String... opts) { for (String opt : opts) { - options.put(opt, false); + options.putIfAbsent(opt, false); } } diff -r 3f9c491b05aa -r cb3d04878117 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Thu Oct 20 12:53:11 2016 -0700 @@ -28,16 +28,26 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collector; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toMap; import static jdk.internal.jshell.tool.ContinuousCompletionProvider.PERFECT_MATCHER; @@ -114,8 +124,8 @@ return mode.getContinuationPrompt(nextId); } - public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) { - return new Setter(messageHandler, at).setFeedback(); + public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at, Consumer retainer) { + return new Setter(messageHandler, at).setFeedback(retainer); } public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) { @@ -126,22 +136,14 @@ return new Setter(messageHandler, at).setTruncation(); } - public boolean setMode(MessageHandler messageHandler, ArgTokenizer at) { - return new Setter(messageHandler, at).setMode(); + public boolean setMode(MessageHandler messageHandler, ArgTokenizer at, Consumer retainer) { + return new Setter(messageHandler, at).setMode(retainer); } public boolean setPrompt(MessageHandler messageHandler, ArgTokenizer at) { return new Setter(messageHandler, at).setPrompt(); } - public String retainFeedback(MessageHandler messageHandler, ArgTokenizer at) { - return new Setter(messageHandler, at).retainFeedback(); - } - - public String retainMode(MessageHandler messageHandler, ArgTokenizer at) { - return new Setter(messageHandler, at).retainMode(); - } - public boolean restoreEncodedModes(MessageHandler messageHandler, String encoded) { return new Setter(messageHandler, new ArgTokenizer("", "")).restoreEncodedModes(encoded); } @@ -177,6 +179,15 @@ selectorMap.put(e.name().toLowerCase(Locale.US), e); } + private static class SelectorSets { + Set cc; + Set ca; + Set cw; + Set cr; + Set cu; + Set ce; + } + /** * Holds all the context of a mode mode */ @@ -197,12 +208,32 @@ String continuationPrompt = ">> "; static class Setting { + final long enumBits; final String format; + Setting(long enumBits, String format) { this.enumBits = enumBits; this.format = format; } + + @Override + public boolean equals(Object o) { + if (o instanceof Setting) { + Setting ing = (Setting) o; + return enumBits == ing.enumBits && format.equals(ing.format); + } else { + return false; + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 67 * hash + (int) (this.enumBits ^ (this.enumBits >>> 32)); + hash = 67 * hash + Objects.hashCode(this.format); + return hash; + } } /** @@ -274,6 +305,25 @@ } } + @Override + public boolean equals(Object o) { + if (o instanceof Mode) { + Mode m = (Mode) o; + return name.equals((m.name)) + && commandFluff == m.commandFluff + && prompt.equals((m.prompt)) + && continuationPrompt.equals((m.continuationPrompt)) + && cases.equals((m.cases)); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } + /** * Set if this mode displays informative/confirmational messages on * commands. @@ -308,13 +358,17 @@ return String.join(RECORD_SEPARATOR, el); } - private boolean add(String field, Setting ing) { - List settings = cases.computeIfAbsent(field, k -> new ArrayList<>()); + private void add(String field, Setting ing) { + List settings = cases.get(field); if (settings == null) { - return false; + settings = new ArrayList<>(); + cases.put(field, settings); + } else { + // remove obscured settings + long mask = ~ing.enumBits; + settings.removeIf(t -> (t.enumBits & mask) == 0); } settings.add(ing); - return true; } void set(String field, @@ -465,6 +519,37 @@ return res; } + private static SelectorSets unpackEnumbits(long enumBits) { + class Unpacker { + + SelectorSets u = new SelectorSets(); + long b = enumBits; + + > Set unpackEnumbits(E[] values) { + Set c = new HashSet<>(); + for (int i = 0; i < values.length; ++i) { + if ((b & (1 << i)) != 0) { + c.add(values[i]); + } + } + b >>>= values.length; + return c; + } + + SelectorSets unpack() { + // inverseof the order they were packed + u.ce = unpackEnumbits(FormatErrors.values()); + u.cu = unpackEnumbits(FormatUnresolved.values()); + u.cr = unpackEnumbits(FormatResolve.values()); + u.cw = unpackEnumbits(FormatWhen.values()); + u.ca = unpackEnumbits(FormatAction.values()); + u.cc = unpackEnumbits(FormatCase.values()); + return u; + } + } + return new Unpacker().unpack(); + } + interface Selector & Selector> { SelectorCollector collector(Setter.SelectorList sl); String doc(); @@ -675,31 +760,197 @@ Setter(MessageHandler messageHandler, ArgTokenizer at) { this.messageHandler = messageHandler; this.at = at; + at.allowedOptions("-retain"); } void fluff(String format, Object... args) { messageHandler.fluff(format, args); } + void hard(String format, Object... args) { + messageHandler.hard(format, args); + } + void fluffmsg(String messageKey, Object... args) { messageHandler.fluffmsg(messageKey, args); } + void hardmsg(String messageKey, Object... args) { + messageHandler.hardmsg(messageKey, args); + } + + boolean showFluff() { + return messageHandler.showFluff(); + } + void errorat(String messageKey, Object... args) { + if (!valid) { + // no spew of errors + return; + } + valid = false; Object[] a2 = Arrays.copyOf(args, args.length + 2); a2[args.length] = at.whole(); messageHandler.errormsg(messageKey, a2); } + String selectorsToString(SelectorSets u) { + StringBuilder sb = new StringBuilder(); + selectorToString(sb, u.cc, FormatCase.values()); + selectorToString(sb, u.ca, FormatAction.values()); + selectorToString(sb, u.cw, FormatWhen.values()); + selectorToString(sb, u.cr, FormatResolve.values()); + selectorToString(sb, u.cu, FormatUnresolved.values()); + selectorToString(sb, u.ce, FormatErrors.values()); + return sb.toString(); + } + + private > void selectorToString(StringBuilder sb, Set c, E[] values) { + if (!c.containsAll(Arrays.asList(values))) { + sb.append(c.stream() + .sorted((x, y) -> x.ordinal() - y.ordinal()) + .map(v -> v.name().toLowerCase(Locale.US)) + .collect(new Collector() { + @Override + public BiConsumer accumulator() { + return StringJoiner::add; + } + + @Override + public Supplier supplier() { + return () -> new StringJoiner(",", (sb.length() == 0)? "" : "-", "") + .setEmptyValue(""); + } + + @Override + public BinaryOperator combiner() { + return StringJoiner::merge; + } + + @Override + public Function finisher() { + return StringJoiner::toString; + } + + @Override + public Set characteristics() { + return Collections.emptySet(); + } + })); + } + } + + // Show format settings -- in a predictable order, for testing... + void showFormatSettings(Mode sm, String f) { + if (sm == null) { + modeMap.entrySet().stream() + .sorted((es1, es2) -> es1.getKey().compareTo(es2.getKey())) + .forEach(m -> showFormatSettings(m.getValue(), f)); + } else { + sm.cases.entrySet().stream() + .filter(ec -> (f == null) + ? !ec.getKey().equals(TRUNCATION_FIELD) + : ec.getKey().equals(f)) + .sorted((ec1, ec2) -> ec1.getKey().compareTo(ec2.getKey())) + .forEach(ec -> { + ec.getValue().forEach(s -> { + hard("/set format %s %s %s %s", + sm.name, ec.getKey(), toStringLiteral(s.format), + selectorsToString(unpackEnumbits(s.enumBits))); + + }); + }); + } + } + + void showTruncationSettings(Mode sm) { + if (sm == null) { + modeMap.values().forEach(m -> showTruncationSettings(m)); + } else { + List trunc = sm.cases.get(TRUNCATION_FIELD); + if (trunc != null) { + trunc.forEach(s -> { + hard("/set truncation %s %s %s", + sm.name, s.format, + selectorsToString(unpackEnumbits(s.enumBits))); + }); + } + } + } + + void showPromptSettings(Mode sm) { + if (sm == null) { + modeMap.values().forEach(m -> showPromptSettings(m)); + } else { + hard("/set prompt %s %s %s", + sm.name, + toStringLiteral(sm.prompt), + toStringLiteral(sm.continuationPrompt)); + } + } + + void showModeSettings(String umode, String msg) { + if (umode == null) { + modeMap.values().forEach(n -> showModeSettings(n)); + } else { + Mode m; + String retained = retainedMap.get(umode); + if (retained == null) { + m = searchForMode(umode, msg); + if (m == null) { + return; + } + umode = m.name; + retained = retainedMap.get(umode); + } else { + m = modeMap.get(umode); + } + if (retained != null) { + Mode rm = new Mode(encodedModeIterator(retained)); + showModeSettings(rm); + hard("/set mode -retain %s", umode); + if (m != null && !m.equals(rm)) { + hard(""); + showModeSettings(m); + } + } else { + showModeSettings(m); + } + } + } + + void showModeSettings(Mode sm) { + hard("/set mode %s %s", + sm.name, sm.commandFluff ? "-command" : "-quiet"); + showPromptSettings(sm); + showFormatSettings(sm, null); + showTruncationSettings(sm); + } + + void showFeedbackSetting() { + if (retainedCurrentMode != null) { + hard("/set feedback -retain %s", retainedCurrentMode.name); + } + if (mode != retainedCurrentMode) { + hard("/set feedback %s", mode.name); + } + } + // For /set prompt "" "" boolean setPrompt() { Mode m = nextMode(); + String prompt = nextFormat(); + String continuationPrompt = nextFormat(); + checkOptionsAndRemainingInput(); + if (valid && prompt == null) { + showPromptSettings(m); + return valid; + } if (valid && m.readOnly) { errorat("jshell.err.not.valid.with.predefined.mode", m.name); - valid = false; + } else if (continuationPrompt == null) { + errorat("jshell.err.continuation.prompt.required"); } - String prompt = valid ? nextFormat() : null; - String continuationPrompt = valid ? nextFormat() : null; if (valid) { m.setPrompts(prompt, continuationPrompt); } else { @@ -714,210 +965,210 @@ * * @return true if successful */ - boolean setMode() { - at.allowedOptions("-command", "-quiet", "-delete"); - String umode = nextModeIdentifier(); - Mode om = null; - String omode = at.next(); - if (valid && omode != null) { - om = toMode(omode); - } - checkOptionsAndRemainingInput(); - boolean commandOption = at.hasOption("-command"); - boolean quietOption = at.hasOption("-quiet"); - boolean deleteOption = at.hasOption("-delete"); - // Only one (or zero) of the options can be used - if (valid && at.optionCount() > 1) { - errorat("jshell.err.conflicting.options"); - valid = false; - } - if (valid) { - Mode m = modeMap.get(umode); - if (m != null && m.readOnly) { - // Cannot make changes to a the built-in modes - errorat("jshell.err.not.valid.with.predefined.mode", m.name); - valid = false; - } else if (deleteOption) { - if (m == null) { + boolean setMode(Consumer retainer) { + class SetMode { + + final String umode; + final String omode; + final boolean commandOption; + final boolean quietOption; + final boolean deleteOption; + final boolean retainOption; + + SetMode() { + at.allowedOptions("-command", "-quiet", "-delete", "-retain"); + umode = nextModeIdentifier(); + omode = nextModeIdentifier(); + checkOptionsAndRemainingInput(); + commandOption = at.hasOption("-command"); + quietOption = at.hasOption("-quiet"); + deleteOption = at.hasOption("-delete"); + retainOption = at.hasOption("-retain"); + } + + void delete() { + // Note: delete, for safety reasons, does NOT do name matching + if (commandOption || quietOption) { + errorat("jshell.err.conflicting.options"); + } else if (!(retainOption ? retainedMap : modeMap).containsKey(umode)) { // Cannot delete a mode that does not exist errorat("jshell.err.mode.unknown", umode); - valid = false; - } else if (mode.name.equals(m.name)) { + } else if (omode != null) { + // old mode is for creation + errorat("jshell.err.unexpected.at.end", omode); + } else if (mode.name.equals(umode)) { // Cannot delete the current mode out from under us errorat("jshell.err.cannot.delete.current.mode", umode); - valid = false; + } else if (retainOption && retainedCurrentMode != null && + retainedCurrentMode.name.equals(umode)) { + // Cannot delete the retained mode or re-start will have an error + errorat("jshell.err.cannot.delete.retained.mode", umode); } else { - // Remove the mode - modeMap.remove(umode); + Mode m = modeMap.get(umode); + if (m != null && m.readOnly) { + errorat("jshell.err.not.valid.with.predefined.mode", umode); + } else { + // Remove the mode + modeMap.remove(umode); + if (retainOption) { + // Remove the retained mode + retainedMap.remove(umode); + updateRetainedModes(); + } + } } - } else { - if (om != null || m == null) { - // We are copying and existing mode and/or creating a - // brand-new mode -- in either case create from scratch - m = (om != null) - ? new Mode(umode, om) - : new Mode(umode); - modeMap.put(umode, m); - fluffmsg("jshell.msg.feedback.new.mode", m.name); - // Set the current mode by name, in case we just smashed - // the current mode - if (umode.equals(mode.name)) { - mode = modeMap.get(mode.name); + } + + void retain() { + if (commandOption || quietOption) { + errorat("jshell.err.conflicting.options"); + } else if (omode != null) { + // old mode is for creation + errorat("jshell.err.unexpected.at.end", omode); + } else { + Mode m = modeMap.get(umode); + if (m == null) { + // can only retain existing modes + errorat("jshell.err.mode.unknown", umode); + } else if (m.readOnly) { + errorat("jshell.err.not.valid.with.predefined.mode", umode); + } else { + // Add to local cache of retained current encodings + retainedMap.put(m.name, m.encode()); + updateRetainedModes(); } } - if (commandOption || quietOption || om == null) { - // set command fluff, if explicit, or wholly new - m.setCommandFluff(!quietOption); + } + + void updateRetainedModes() { + // Join all the retained encodings + String encoded = String.join(RECORD_SEPARATOR, retainedMap.values()); + // Retain it + retainer.accept(encoded); + } + + void create() { + if (commandOption && quietOption) { + errorat("jshell.err.conflicting.options"); + } else if (!commandOption && !quietOption) { + errorat("jshell.err.mode.creation"); + } else if (modeMap.containsKey(umode)) { + // Mode already exists + errorat("jshell.err.mode.exists", umode); + } else { + Mode om = searchForMode(omode); + if (valid) { + // We are copying an existing mode and/or creating a + // brand-new mode -- in either case create from scratch + Mode m = (om != null) + ? new Mode(umode, om) + : new Mode(umode); + modeMap.put(umode, m); + fluffmsg("jshell.msg.feedback.new.mode", m.name); + m.setCommandFluff(commandOption); + } } } + + boolean set() { + if (valid && !commandOption && !quietOption && !deleteOption && + omode == null && !retainOption) { + // Not a creation, deletion, or retain -- show mode(s) + showModeSettings(umode, "jshell.err.mode.creation"); + } else if (valid && umode == null) { + errorat("jshell.err.missing.mode"); + } else if (valid && deleteOption) { + delete(); + } else if (valid && retainOption) { + retain(); + } else if (valid) { + create(); + } + if (!valid) { + fluffmsg("jshell.msg.see", "/help /set mode"); + } + return valid; + } } - if (!valid) { - fluffmsg("jshell.msg.see", "/help /set mode"); - } - return valid; + return new SetMode().set(); } - // For /set feedback - boolean setFeedback() { + // For /set format "" ... + boolean setFormat() { Mode m = nextMode(); - if (valid) { - mode = m; - fluffmsg("jshell.msg.feedback.mode", mode.name); + String field = toIdentifier(next(), "jshell.err.field.name"); + String format = nextFormat(); + if (valid && format == null) { + if (field != null && m != null && !m.cases.containsKey(field)) { + errorat("jshell.err.field.name", field); + } else { + showFormatSettings(m, field); + } } else { - fluffmsg("jshell.msg.see", "/help /set feedback"); - printFeedbackModes(); + installFormat(m, field, format, "/help /set format"); } return valid; } - // For /set format "" ... - boolean setFormat() { - Mode m = nextMode(); - if (valid && m.readOnly) { - errorat("jshell.err.not.valid.with.predefined.mode", m.name); - valid = false; - } - String field = valid - ? toIdentifier(at.next(), "jshell.err.missing.field", "jshell.err.field.name") - : null; - String format = valid ? nextFormat() : null; - return installFormat(m, field, format, "/help /set format"); - } - // For /set truncation ... boolean setTruncation() { Mode m = nextMode(); - if (valid && m.readOnly) { - errorat("jshell.err.not.valid.with.predefined.mode", m.name); - valid = false; - } - String length = at.next(); + String length = next(); if (length == null) { - errorat("jshell.err.truncation.expected.length"); - valid = false; + showTruncationSettings(m); } else { try { // Assure that integer format is correct Integer.parseUnsignedInt(length); } catch (NumberFormatException ex) { errorat("jshell.err.truncation.length.not.integer", length); - valid = false; } + // install length into an internal format field + installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation"); } - // install length into an internal format field - return installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation"); - } - - String retainFeedback() { - String umode = at.next(); - if (umode != null) { - toModeIdentifier(umode); - Mode m = valid ? toMode(umode) : null; - if (valid && !m.readOnly && !retainedMap.containsKey(m.name)) { - errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined"); - valid = false; - } - if (valid) { - mode = m; - retainedCurrentMode = m; - fluffmsg("jshell.msg.feedback.mode", mode.name); - } else { - fluffmsg("jshell.msg.see", "/help /retain feedback"); - return null; - } - } - return mode.name; + return valid; } - /** - * Retain (or delete from retention) a previously set mode. - * - * @return all retained modes encoded into a String - */ - String retainMode() { - at.allowedOptions("-delete"); - String umode = nextModeIdentifier(); - // -delete is the only valid option, fail for anything else + // For /set feedback + boolean setFeedback(Consumer retainer) { + String umode = next(); checkOptionsAndRemainingInput(); - boolean deleteOption = at.hasOption("-delete"); - // Lookup the mode - Mode m; - if (!valid) { - m = null; - // Skip this stuff, we have failed already - } else if (deleteOption) { - // If delete, allow for deleting, from retention, a mode that - // has been locally deleted but is retained. - // Also require the full name. - m = modeMap.get(umode); - if (m == null && !retainedMap.containsKey(umode)) { - errorat("jshell.err.mode.unknown", umode); - valid = false; - } - } else { - // For retain do normal lookup and checking - m = toMode(umode); - } - - // Built-in modes cannot be retained or deleted - if (valid && m != null && m.readOnly) { - errorat("jshell.err.not.valid.with.predefined.mode", umode); - valid = false; + boolean retainOption = at.hasOption("-retain"); + if (valid && umode == null && !retainOption) { + showFeedbackSetting(); + hard(""); + showFeedbackModes(); + return true; } if (valid) { - if (deleteOption) { - if (mode.name.equals(umode)) { - // Cannot delete the current mode out from under us - errorat("jshell.err.cannot.delete.current.mode", umode); - valid = false; - } else if (retainedCurrentMode != null && retainedCurrentMode.name.equals(umode)) { - // Cannot delete the retained mode or re-start has error - errorat("jshell.err.cannot.delete.retained.mode", umode); - valid = false; - } else { - // Delete the mode - modeMap.remove(umode); - retainedMap.remove(umode); + Mode m = umode == null + ? mode + : searchForMode(toModeIdentifier(umode)); + if (valid && retainOption && !m.readOnly && !retainedMap.containsKey(m.name)) { + errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined"); + } + if (valid) { + if (umode != null) { + mode = m; + fluffmsg("jshell.msg.feedback.mode", mode.name); } - } else { - // Retain the current encoding - retainedMap.put(m.name, m.encode()); + if (retainOption) { + retainedCurrentMode = m; + retainer.accept(m.name); + } } } - if (valid) { - // Join all the retained encodings - return String.join(RECORD_SEPARATOR, retainedMap.values()); - } else { - fluffmsg("jshell.msg.see", "/help /retain mode"); - return null; + if (!valid) { + fluffmsg("jshell.msg.see", "/help /set feedback"); + return false; } + return true; } boolean restoreEncodedModes(String allEncoded) { try { // Iterate over each record in each encoded mode - String[] ms = allEncoded.split(RECORD_SEPARATOR); - Iterator itr = Arrays.asList(ms).iterator(); + Iterator itr = encodedModeIterator(allEncoded); while (itr.hasNext()) { // Reconstruct the encoded mode Mode m = new Mode(itr); @@ -934,50 +1185,60 @@ } } + Iterator encodedModeIterator(String encoded) { + String[] ms = encoded.split(RECORD_SEPARATOR); + return Arrays.asList(ms).iterator(); + } + // install the format of a field under parsed selectors - boolean installFormat(Mode m, String field, String format, String help) { + void installFormat(Mode m, String field, String format, String help) { String slRaw; List slList = new ArrayList<>(); - while (valid && (slRaw = at.next()) != null) { + while (valid && (slRaw = next()) != null) { SelectorList sl = new SelectorList(); sl.parseSelectorList(slRaw); slList.add(sl); } + checkOptionsAndRemainingInput(); if (valid) { - if (slList.isEmpty()) { + if (m.readOnly) { + errorat("jshell.err.not.valid.with.predefined.mode", m.name); + } else if (slList.isEmpty()) { // No selectors specified, then always the format m.set(field, ALWAYS, format); } else { // Set the format of the field for specified selector slList.stream() .forEach(sl -> m.set(field, - sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(), - sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(), - format)); + sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(), + sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(), + format)); } } else { fluffmsg("jshell.msg.see", help); } - return valid; } void checkOptionsAndRemainingInput() { - if (!valid) { - return; - } String junk = at.remainder(); if (!junk.isEmpty()) { errorat("jshell.err.unexpected.at.end", junk); - valid = false; } else { String bad = at.badOptions(); if (!bad.isEmpty()) { errorat("jshell.err.unknown.option", bad); - valid = false; } } } + String next() { + String s = at.next(); + if (s == null) { + checkOptionsAndRemainingInput(); + } + return s; + } + /** * Check that the specified string is an identifier (Java identifier). * If null display the missing error. If it is not an identifier, @@ -985,45 +1246,41 @@ * * @param id the string to check, MUST be the most recently retrieved * token from 'at'. - * @param missing the resource error to display if null + * @param missing null for no null error, otherwise the resource error to display if id is null * @param err the resource error to display if not an identifier * @return the identifier string, or null if null or not an identifier */ - String toIdentifier(String id, String missing, String err) { - if (id == null) { - errorat(missing); - valid = false; + private String toIdentifier(String id, String err) { + if (!valid || id == null) { return null; } if (at.isQuoted() || !id.codePoints().allMatch(cp -> Character.isJavaIdentifierPart(cp))) { errorat(err, id); - valid = false; return null; } return id; } - String toModeIdentifier(String id) { - return toIdentifier(id, "jshell.err.missing.mode", "jshell.err.mode.name"); + private String toModeIdentifier(String id) { + return toIdentifier(id, "jshell.err.mode.name"); } - String nextModeIdentifier() { - return toModeIdentifier(at.next()); + private String nextModeIdentifier() { + return toModeIdentifier(next()); } - Mode nextMode() { + private Mode nextMode() { String umode = nextModeIdentifier(); - return toMode(umode); + return searchForMode(umode); } - Mode toMode(String umode) { - if (!valid) { - return null; - } - if (umode == null) { - errorat("jshell.err.missing.mode"); - valid = false; + private Mode searchForMode(String umode) { + return searchForMode(umode, null); + } + + private Mode searchForMode(String umode, String msg) { + if (!valid || umode == null) { return null; } Mode m = modeMap.get(umode); @@ -1038,39 +1295,101 @@ if (matches.length == 1) { return matches[0]; } else { - valid = false; + if (msg != null) { + hardmsg(msg, ""); + } if (matches.length == 0) { errorat("jshell.err.feedback.does.not.match.mode", umode); } else { errorat("jshell.err.feedback.ambiguous.mode", umode); } - printFeedbackModes(); + if (showFluff()) { + showFeedbackModes(); + } return null; } } - void printFeedbackModes() { - fluffmsg("jshell.msg.feedback.mode.following"); + void showFeedbackModes() { + if (!retainedMap.isEmpty()) { + hardmsg("jshell.msg.feedback.retained.mode.following"); + retainedMap.keySet().stream() + .sorted() + .forEach(mk -> hard(" %s", mk)); + } + hardmsg("jshell.msg.feedback.mode.following"); modeMap.keySet().stream() - .forEach(mk -> fluff(" %s", mk)); + .sorted() + .forEach(mk -> hard(" %s", mk)); + } + + // Read and test if the format string is correctly + private String nextFormat() { + return toFormat(next()); } // Test if the format string is correctly - final String nextFormat() { - String format = at.next(); - if (format == null) { - errorat("jshell.err.feedback.expected.format"); - valid = false; + private String toFormat(String format) { + if (!valid || format == null) { return null; } if (!at.isQuoted()) { errorat("jshell.err.feedback.must.be.quoted", format); - valid = false; - return null; + return null; } return format; } + // Convert to a quoted string + private String toStringLiteral(String s) { + StringBuilder sb = new StringBuilder(); + sb.append('"'); + final int length = s.length(); + for (int offset = 0; offset < length;) { + final int codepoint = s.codePointAt(offset); + + switch (codepoint) { + case '\b': + sb.append("\\b"); + break; + case '\t': + sb.append("\\t"); + break; + case '\n': + sb.append("\\n"); + break; + case '\f': + sb.append("\\f"); + break; + case '\r': + sb.append("\\r"); + break; + case '\"': + sb.append("\\\""); + break; + case '\'': + sb.append("\\'"); + break; + case '\\': + sb.append("\\\\"); + break; + default: + if (codepoint < 040) { + sb.append(String.format("\\%o", codepoint)); + } else { + sb.appendCodePoint(codepoint); + } + break; + } + + // do something with the codepoint + offset += Character.charCount(codepoint); + + } + sb.append('"'); + return sb.toString(); + } + class SelectorList { SelectorCollector cases = new SelectorCollector<>(FormatCase.all); @@ -1088,19 +1407,16 @@ Selector sel = selectorMap.get(as); if (sel == null) { errorat("jshell.err.feedback.not.a.valid.selector", as, s); - valid = false; return; } SelectorCollector collector = sel.collector(this); if (lastCollector == null) { if (!collector.isEmpty()) { errorat("jshell.err.feedback.multiple.sections", as, s); - valid = false; return; } } else if (collector != lastCollector) { errorat("jshell.err.feedback.different.selector.kinds", as, s); - valid = false; return; } collector.add(sel); diff -r 3f9c491b05aa -r cb3d04878117 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Oct 20 12:53:11 2016 -0700 @@ -204,12 +204,13 @@ JShell state = null; Subscription shutdownSubscription = null; + static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false); + private boolean debug = false; public boolean testPrompt = false; private String cmdlineClasspath = null; private String startup = null; - private String[] editor = null; - private boolean editorWait = false; + private EditorSetting editor = BUILT_IN_EDITOR; // Commands and snippets which should be replayed private List replayableHistory; @@ -273,7 +274,8 @@ * @param format printf format * @param args printf args */ - void hard(String format, Object... args) { + @Override + public void hard(String format, Object... args) { rawout(feedback.getPre() + format + feedback.getPost(), args); } @@ -288,6 +290,15 @@ } /** + * Should optional informative be displayed? + * @return true if they should be displayed + */ + @Override + public boolean showFluff() { + return feedback.shouldDisplayCommandFluff() && interactive(); + } + + /** * Optional output * * @param format printf format @@ -295,7 +306,7 @@ */ @Override public void fluff(String format, Object... args) { - if (feedback.shouldDisplayCommandFluff() && interactive()) { + if (showFluff()) { hard(format, args); } } @@ -307,7 +318,7 @@ * @param args printf args */ void fluffRaw(String format, Object... args) { - if (feedback.shouldDisplayCommandFluff() && interactive()) { + if (showFluff()) { rawout(format, args); } } @@ -389,7 +400,8 @@ * @param key the resource key * @param args */ - void hardmsg(String key, Object... args) { + @Override + public void hardmsg(String key, Object... args) { cmdout.println(prefix(messageFormat(key, args))); } @@ -428,7 +440,7 @@ */ @Override public void fluffmsg(String key, Object... args) { - if (feedback.shouldDisplayCommandFluff() && interactive()) { + if (showFluff()) { hardmsg(key, args); } } @@ -502,16 +514,9 @@ } // Read retained editor setting (if any) - String editorString = prefs.get(EDITOR_KEY, ""); - if (editorString == null || editorString.isEmpty()) { - editor = null; - } else { - char waitMarker = editorString.charAt(0); - if (waitMarker == '-' || waitMarker == '*') { - editorWait = waitMarker == '-'; - editorString = editorString.substring(1); - } - editor = editorString.split(RECORD_SEPARATOR); + editor = EditorSetting.fromPrefs(prefs); + if (editor == null) { + editor = BUILT_IN_EDITOR; } resetState(); // Initialize @@ -681,9 +686,24 @@ } @Override + public void hard(String format, Object... args) { + //ignore + } + + @Override + public void hardmsg(String messageKey, Object... args) { + //ignore + } + + @Override public void errormsg(String messageKey, Object... args) { startmsg(messageKey, args); } + + @Override + public boolean showFluff() { + return false; + } } private void resetState() { @@ -745,7 +765,7 @@ startUpRun(getResourceString("startup.feedback")); // These predefined modes are read-only feedback.markModesReadOnly(); - // Restore user defined modes retained on previous run with /retain mode + // Restore user defined modes retained on previous run with /set mode -retain String encoded = prefs.get(MODE_KEY, null); if (encoded != null && !encoded.isEmpty()) { if (!feedback.restoreEncodedModes(initmh, encoded)) { @@ -755,7 +775,7 @@ } if (commandLineFeedbackMode != null) { // The feedback mode to use was specified on the command line, use it - if (!feedback.setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) { + if (!setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) { regenerateOnDeath = false; } commandLineFeedbackMode = null; @@ -763,8 +783,8 @@ String fb = prefs.get(FEEDBACK_KEY, null); if (fb != null) { // Restore the feedback mode to use that was retained - // on a previous run with /retain feedback - feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb)); + // on a previous run with /set feedback -retain + setFeedback(initmh, new ArgTokenizer("previous retain feedback", "-retain " + fb)); } } } @@ -1227,14 +1247,6 @@ "editor", fileCompletions(Files::isExecutable), "start", FILE_COMPLETION_PROVIDER), STARTSWITH_MATCHER))); - registerCommand(new Command("/retain", - arg -> cmdRetain(arg), - new ContinuousCompletionProvider(Map.of( - "feedback", feedback.modeCompletions(), - "mode", feedback.modeCompletions(), - "editor", fileCompletions(Files::isExecutable), - "start", FILE_COMPLETION_PROVIDER), - STARTSWITH_MATCHER))); registerCommand(new Command("/?", "help.quest", arg -> cmdHelp(arg), @@ -1293,9 +1305,6 @@ private static final String[] SET_SUBCOMMANDS = new String[]{ "format", "truncation", "feedback", "mode", "prompt", "editor", "start"}; - private static final String[] RETAIN_SUBCOMMANDS = new String[]{ - "feedback", "mode", "editor", "start"}; - final boolean cmdSet(String arg) { String cmd = "/set"; ArgTokenizer at = new ArgTokenizer(cmd, arg.trim()); @@ -1304,95 +1313,61 @@ return false; } switch (which) { + case "_retain": { + errormsg("jshell.err.setting.to.retain.must.be.specified", at.whole()); + return false; + } + case "_blank": { + // show top-level settings + new SetEditor().set(); + showSetStart(); + setFeedback(this, at); // no args so shows feedback setting + hardmsg("jshell.msg.set.show.mode.settings"); + return true; + } case "format": return feedback.setFormat(this, at); case "truncation": return feedback.setTruncation(this, at); case "feedback": - return feedback.setFeedback(this, at); + return setFeedback(this, at); case "mode": - return feedback.setMode(this, at); + return feedback.setMode(this, at, + retained -> prefs.put(MODE_KEY, retained)); case "prompt": return feedback.setPrompt(this, at); case "editor": - return setEditor(at, true); + return new SetEditor(at).set(); case "start": - return setStart(cmd, at, true); + return setStart(at); default: errormsg("jshell.err.arg", cmd, at.val()); return false; } } - final boolean cmdRetain(String arg) { - String cmd = "/retain"; - ArgTokenizer at = new ArgTokenizer(cmd, arg.trim()); - String which = subCommand(cmd, at, RETAIN_SUBCOMMANDS); - if (which == null) { - return false; - } - switch (which) { - case "feedback": { - String fb = feedback.retainFeedback(this, at); - if (fb != null) { - // If a feedback mode has been set now, or in the past, retain it - prefs.put(FEEDBACK_KEY, fb); - return true; - } - return false; - } - case "mode": - String retained = feedback.retainMode(this, at); - if (retained != null) { - // Retain this mode and all previously retained modes - prefs.put(MODE_KEY, retained); - return true; - } - return false; - case "editor": - if (!setEditor(at, false)) { - return false; - } - // retain editor setting - prefs.put(EDITOR_KEY, (editor == null) - ? "" - : (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor)); - return true; - case "start": { - if (!setStart(cmd, at, false)) { - return false; - } - // retain startup setting - prefs.put(STARTUP_KEY, startup); - return true; - } - default: - errormsg("jshell.err.arg", cmd, at.val()); - return false; - } + boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) { + return feedback.setFeedback(messageHandler, at, + fb -> prefs.put(FEEDBACK_KEY, fb)); } - // Print the help doc for the specified sub-command - boolean printSubCommandHelp(String cmd, ArgTokenizer at, String helpPrefix, String[] subs) { - String which = subCommand(cmd, at, subs); - if (which == null) { - return false; + // Find which, if any, sub-command matches. + // Return null on error + String subCommand(String cmd, ArgTokenizer at, String[] subs) { + at.allowedOptions("-retain"); + String sub = at.next(); + if (sub == null) { + // No sub-command was given + return at.hasOption("-retain") + ? "_retain" + : "_blank"; } - hardrb(helpPrefix + which); - return true; - } - - // Find which, if any, sub-command matches - String subCommand(String cmd, ArgTokenizer at, String[] subs) { - String[] matches = at.next(subs); - if (matches == null) { - // No sub-command was given - errormsg("jshell.err.sub.arg", cmd); - return null; - } + String[] matches = Arrays.stream(subs) + .filter(s -> s.startsWith(sub)) + .toArray(size -> new String[size]); if (matches.length == 0) { // There are no matching sub-commands - errormsg("jshell.err.arg", cmd, at.val()); + errormsg("jshell.err.arg", cmd, sub); fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs) .collect(Collectors.joining(", ")) ); @@ -1400,7 +1375,7 @@ } if (matches.length > 1) { // More than one sub-command matches the initial characters provided - errormsg("jshell.err.sub.ambiguous", cmd, at.val()); + errormsg("jshell.err.sub.ambiguous", cmd, sub); fluffmsg("jshell.msg.use.one.of", Arrays.stream(matches) .collect(Collectors.joining(", ")) ); @@ -1409,67 +1384,219 @@ return matches[0]; } - // The sub-command: /set editor > - boolean setEditor(ArgTokenizer at, boolean argsRequired) { - at.allowedOptions("-default", "-wait"); - String prog = at.next(); - List ed = new ArrayList<>(); - while (at.val() != null) { - ed.add(at.val()); - at.nextToken(); + static class EditorSetting { + + static String BUILT_IN_REP = "-default"; + static char WAIT_PREFIX = '-'; + static char NORMAL_PREFIX = '*'; + + final String[] cmd; + final boolean wait; + + EditorSetting(String[] cmd, boolean wait) { + this.wait = wait; + this.cmd = cmd; + } + + // returns null if not stored in preferences + static EditorSetting fromPrefs(Preferences prefs) { + // Read retained editor setting (if any) + String editorString = prefs.get(EDITOR_KEY, ""); + if (editorString == null || editorString.isEmpty()) { + return null; + } else if (editorString.equals(BUILT_IN_REP)) { + return BUILT_IN_EDITOR; + } else { + boolean wait = false; + char waitMarker = editorString.charAt(0); + if (waitMarker == WAIT_PREFIX || waitMarker == NORMAL_PREFIX) { + wait = waitMarker == WAIT_PREFIX; + editorString = editorString.substring(1); + } + String[] cmd = editorString.split(RECORD_SEPARATOR); + return new EditorSetting(cmd, wait); + } + } + + void toPrefs(Preferences prefs) { + prefs.put(EDITOR_KEY, (this == BUILT_IN_EDITOR) + ? BUILT_IN_REP + : (wait ? WAIT_PREFIX : NORMAL_PREFIX) + String.join(RECORD_SEPARATOR, cmd)); + } + + @Override + public boolean equals(Object o) { + if (o instanceof EditorSetting) { + EditorSetting ed = (EditorSetting) o; + return Arrays.equals(cmd, ed.cmd) && wait == ed.wait; + } else { + return false; + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 71 * hash + Arrays.deepHashCode(this.cmd); + hash = 71 * hash + (this.wait ? 1 : 0); + return hash; } + } + + class SetEditor { + + private final ArgTokenizer at; + private final String[] command; + private final boolean hasCommand; + private final boolean defaultOption; + private final boolean waitOption; + private final boolean retainOption; + + SetEditor(ArgTokenizer at) { + at.allowedOptions("-default", "-wait", "-retain"); + String prog = at.next(); + List ed = new ArrayList<>(); + while (at.val() != null) { + ed.add(at.val()); + at.nextToken(); // so that options are not interpreted as jshell options + } + this.at = at; + this.command = ed.toArray(new String[ed.size()]); + this.hasCommand = command.length > 0; + this.defaultOption = at.hasOption("-default"); + this.waitOption = at.hasOption("-wait"); + this.retainOption = at.hasOption("-retain"); + } + + SetEditor() { + this(new ArgTokenizer("", "")); + } + + boolean set() { + if (!check()) { + return false; + } + if (!hasCommand && !defaultOption && !retainOption) { + // No settings or -retain, so this is a query + EditorSetting retained = EditorSetting.fromPrefs(prefs); + if (retained != null) { + // retained editor is set + hard("/set editor -retain %s", format(retained)); + } + if (retained == null || !retained.equals(editor)) { + // editor is not retained or retained is different from set + hard("/set editor %s", format(editor)); + } + return true; + } + install(); + if (retainOption) { + editor.toPrefs(prefs); + fluffmsg("jshell.msg.set.editor.retain", format(editor)); + } + return true; + } + + private boolean check() { + if (!checkOptionsAndRemainingInput(at)) { + return false; + } + if (hasCommand && defaultOption) { + errormsg("jshell.err.default.option.or.program", at.whole()); + return false; + } + if (waitOption && !hasCommand) { + errormsg("jshell.err.wait.applies.to.external.editor", at.whole()); + return false; + } + return true; + } + + private void install() { + if (hasCommand) { + editor = new EditorSetting(command, waitOption); + } else if (defaultOption) { + editor = BUILT_IN_EDITOR; + } else { + return; + } + fluffmsg("jshell.msg.set.editor.set", format(editor)); + } + + private String format(EditorSetting ed) { + if (ed == BUILT_IN_EDITOR) { + return "-default"; + } else { + Stream elems = Arrays.stream(ed.cmd); + if (ed.wait) { + elems = Stream.concat(Stream.of("-wait"), elems); + } + return elems.collect(joining(" ")); + } + } + } + + // The sub-command: /set start + boolean setStart(ArgTokenizer at) { + at.allowedOptions("-default", "-none", "-retain"); + String fn = at.next(); if (!checkOptionsAndRemainingInput(at)) { return false; } boolean defaultOption = at.hasOption("-default"); - boolean waitOption = at.hasOption("-wait"); - if (prog != null) { - if (defaultOption) { - errormsg("jshell.err.default.option.or.program", at.whole()); + boolean noneOption = at.hasOption("-none"); + boolean retainOption = at.hasOption("-retain"); + boolean hasFile = fn != null; + + int argCount = (defaultOption ? 1 : 0) + (noneOption ? 1 : 0) + (hasFile ? 1 : 0); + if (argCount > 1) { + errormsg("jshell.err.option.or.filename", at.whole()); + return false; + } + if (argCount == 0 && !retainOption) { + // no options or filename, show current setting + showSetStart(); + return true; + } + if (hasFile) { + String init = readFile(fn, "/set start"); + if (init == null) { return false; } - editor = ed.toArray(new String[ed.size()]); - editorWait = waitOption; - fluffmsg("jshell.msg.set.editor.set", prog); + startup = init; } else if (defaultOption) { - if (waitOption) { - errormsg("jshell.err.wait.applies.to.external.editor", at.whole()); - return false; - } - editor = null; - } else if (argsRequired) { - errormsg("jshell.err.set.editor.arg"); - return false; + startup = DEFAULT_STARTUP; + } else if (noneOption) { + startup = ""; + } + if (retainOption) { + // retain startup setting + prefs.put(STARTUP_KEY, startup); } return true; } - // The sub-command: /set start - boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) { - at.allowedOptions("-default", "-none"); - String fn = at.next(); - if (!checkOptionsAndRemainingInput(at)) { - return false; + void showSetStart() { + String retained = prefs.get(STARTUP_KEY, null); + if (retained != null) { + showSetStart(true, retained); } - int argCount = at.optionCount() + ((fn != null) ? 1 : 0); - if (argCount > 1 || argsRequired && argCount == 0) { - errormsg("jshell.err.option.or.filename", at.whole()); - return false; + if (retained == null || !startup.equals(retained)) { + showSetStart(false, startup); } - if (fn != null) { - String init = readFile(fn, cmd + " start"); - if (init == null) { - return false; - } else { - startup = init; - return true; - } - } else if (at.hasOption("-default")) { - startup = DEFAULT_STARTUP; - } else if (at.hasOption("-none")) { - startup = ""; + } + + void showSetStart(boolean isRetained, String start) { + String cmd = "/set start" + (isRetained ? " -retain " : " "); + String stset; + if (start.equals(DEFAULT_STARTUP)) { + stset = cmd + "-default"; + } else if (start.isEmpty()) { + stset = cmd + "-none"; + } else { + stset = prefix("startup.jsh:\n" + start + "\n" + cmd + "startup.jsh", ""); } - return true; + hard(stset); } boolean cmdClasspath(String arg) { @@ -1559,17 +1686,18 @@ Command[] matches = commands.values().stream() .filter(c -> c.command.startsWith(subject)) .toArray(size -> new Command[size]); - at.mark(); - String sub = at.next(); - if (sub != null && matches.length == 1) { + if (matches.length == 1) { String cmd = matches[0].command; - switch (cmd) { - case "/set": - at.rewind(); - return printSubCommandHelp(cmd, at, "help.set.", SET_SUBCOMMANDS); - case "/retain": - at.rewind(); - return printSubCommandHelp(cmd, at, "help.retain.", RETAIN_SUBCOMMANDS); + if (cmd.equals("/set")) { + // Print the help doc for the specified sub-command + String which = subCommand(cmd, at, SET_SUBCOMMANDS); + if (which == null) { + return false; + } + if (!which.equals("_blank")) { + hardrb("help.set." + which); + return true; + } } } if (matches.length > 0) { @@ -1813,7 +1941,7 @@ String src = sb.toString(); Consumer saveHandler = new SaveHandler(src, srcSet); Consumer errorHandler = s -> hard("Edit Error: %s", s); - if (editor == null) { + if (editor == BUILT_IN_EDITOR) { try { EditPad.edit(errorHandler, src, saveHandler); } catch (RuntimeException ex) { @@ -1822,8 +1950,8 @@ return false; } } else { - ExternalEditor.edit(editor, errorHandler, src, saveHandler, input, - editorWait, this::hardrb); + ExternalEditor.edit(editor.cmd, errorHandler, src, saveHandler, input, + editor.wait, this::hardrb); } return true; } diff -r 3f9c491b05aa -r cb3d04878117 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java Thu Oct 20 12:53:11 2016 -0700 @@ -37,5 +37,11 @@ void fluffmsg(String messageKey, Object... args); + void hard(String format, Object... args); + + void hardmsg(String messageKey, Object... args); + void errormsg(String messageKey, Object... args); + + boolean showFluff(); } diff -r 3f9c491b05aa -r cb3d04878117 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Oct 20 12:53:11 2016 -0700 @@ -52,12 +52,17 @@ jshell.err.no.such.command.or.snippet.id = No such command or snippet id: {0} jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1} -jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument jshell.msg.set.editor.set = Editor set to: {0} +jshell.msg.set.editor.retain = Editor setting retained: {0} jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0} jshell.msg.try.set.editor = Try /set editor to use external editor. jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode. -jshell.err.wait.applies.to.external.editor = -wait applies to external editors, cannot be used with -default +jshell.err.wait.applies.to.external.editor = -wait applies to external editors + +jshell.err.setting.to.retain.must.be.specified = The setting to retain must be specified -- {0} +jshell.msg.set.show.mode.settings = \nTo show mode settings use ''/set prompt'', ''/set truncation'', ...\n\ +or use ''/set mode'' followed by the feedback mode name. +jshell.err.continuation.prompt.required = Continuation prompt required -- {0} jshell.msg.try.command.without.args = Try ''{0}'' without arguments. jshell.msg.no.active = There are no active definitions. @@ -104,12 +109,10 @@ jshell.err.mode.name = Expected a feedback mode name: {0} jshell.err.missing.mode = Missing the feedback mode -- {0} jshell.err.field.name = Expected a field name: {0} -- {1} -jshell.err.missing.field = Missing the field name -- {0} jshell.err.mode.unknown = No feedback mode named: {0} -- {1} jshell.err.feedback.does.not.match.mode = Does not match any current feedback mode: {0} -- {1} jshell.err.feedback.ambiguous.mode = Matches more then one current feedback mode: {0} -- {1} -jshell.err.feedback.expected.format = Expected format missing -- {0} jshell.err.feedback.must.be.quoted = Format ''{0}'' must be quoted -- {1} jshell.err.feedback.not.a.valid.selector = Not a valid selector ''{0}'' in ''{1}'' -- {2} jshell.err.feedback.multiple.sections = Selector kind in multiple sections of selector list ''{0}'' in ''{1}'' -- {2} @@ -117,22 +120,25 @@ jshell.msg.feedback.new.mode = Created new feedback mode: {0} jshell.msg.feedback.mode = Feedback mode: {0} -jshell.msg.feedback.mode.following = The feedback mode should be one of the following: +jshell.msg.feedback.mode.following = Available feedback modes: +jshell.msg.feedback.retained.mode.following = Retained feedback modes: +jshell.err.mode.creation = To create a new mode either the -command or the -quiet option must be used -- {0} +jshell.err.mode.exists = Mode to be created already exists: {0} -- {1} jshell.err.truncation.expected.length = Expected truncation length -- {0} jshell.err.truncation.length.not.integer = Truncation length must be an integer: {0} -- {1} jshell.err.not.valid.with.predefined.mode = Not valid with a predefined mode: {0} -- {1} jshell.err.retained.feedback.mode.must.be.retained.or.predefined = \ -''/retain feedback '' requires that is predefined or has been retained with ''/retain mode'' -- {0} +''/set feedback -retain '' requires that is predefined or has been retained with ''/set mode -retain'' -- {0} jshell.err.unknown.option = Unknown option: {0} -- {1} jshell.err.default.option.or.program = Specify -default option or program, not both -- {0} -jshell.err.option.or.filename = Specify either one option or a startup file name -- {0} +jshell.err.option.or.filename = Specify no more than one of -default, -none, or a startup file name -- {0} jshell.err.unexpected.at.end = Unexpected arguments at end of command: {0} -- {1} jshell.err.conflicting.options = Conflicting options -- {0} jshell.err.cannot.delete.current.mode = The current feedback mode ''{0}'' cannot be deleted, use ''/set feedback'' first -- {1} -jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/retain feedback'' first -- {1} +jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/set feedback -retain'' first -- {1} jshell.err.may.not.specify.options.and.snippets = Options and snippets must not both be used: {0} jshell.err.no.such.snippets = No such snippet: {0} jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1} @@ -374,36 +380,20 @@ The contents of the specified become the default start-up snippets and commands.\n\n\ /set feedback \n\t\ Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\ -/set mode [] [-command|-quiet|-delete]\n\t\ +/set mode [] -command|-quiet|-delete\n\t\ Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\ /set prompt "" ""\n\t\ Set the displayed prompts for a given feedback mode.\n\n\ /set truncation ...\n\t\ - Set the maximum length of a displayed value\n\ + Set the maximum length of a displayed value.\n\n\ /set format "" ...\n\t\ - Configure a feedback mode by setting the format of a field when the selector matchs.\n\n\ + Configure a feedback mode by setting the format of a field when the selector matches.\n\n\ +/set\n\t\ + Show editor, start, and feedback settings as /set commands.\n\t\ + To show the settings of any of the above, omit the set value.\n\n\ To get more information about one of these forms, use /help with the form specified.\n\ For example: /help /set format -help.retain.summary = retain jshell configuration information for subsequent sessions -help.retain.args = editor|start|feedback|mode -help.retain =\ -Retain jshell configuration information for future invocations of the jshell tool,\n\ -including: the external editor to use, the start-up definitions to use, the\n\ -configuration of a feedback mode, or the feedback mode to use.\n\ -\n\ -/retain editor [ ...]\n\t\ - Specify the command to launch for the /edit command.\n\t\ - The is an operating system dependent string.\n\n\ -/retain start []\n\t\ - The contents of the specified become the default start-up snippets and commands.\n\n\ -/retain feedback []\n\t\ - Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\ -/retain mode \n\t\ - Create a user-defined feedback mode, optionally copying from an existing mode.\n\n\ -To get more information about one of these forms, use /help with the form specified.\n\ -For example: /help /retain feedback - help.quest.summary = get information about jshell help.quest.args = [|] help.quest =\ @@ -467,11 +457,24 @@ possible fully qualified names based on the content of the specified classpath.\n\t\t\ The "" is either Alt-F1 or Alt-Enter, depending on the platform. +help.set._retain = \ +The '-retain' option saves a setting so that it is used in future sessions.\n\ +The -retain option can be used on the following forms of /set:\n\n\t\ +/set editor -retain\n\t\ +/set start -retain\n\t\ +/set feedback -retain\n\t\ +/set mode -retain\n\n\ +See these commands for more detail -- for example /help /set editor + help.set.format = \ -Set the format for reporting a snippet event.\n\ +Set the format for reporting a snippet event:\n\ \n\t\ /set format "" ...\n\ \n\ +Show the format settings:\n\ +\n\t\ +/set format [ []]\n\ +\n\ Where is the name of a previously defined feedback mode -- see '/help /set mode'.\n\ Where is the name of context-specific format to define.\n\ Where is a quoted string which will be the value of the field if one of\n\ @@ -541,13 +544,24 @@ /set format myformat action 'Update replaced' replaced-update\n\t\ /set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t\ /set format myformat display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update\n\n\ -Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n +Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\ +\n\ +The form without shows the current format settings.\n\ +When the is specified only the format settings for that mode are shown.\n\ +When both the and are specified only the format settings for that\n\ +mode and field are shown. Example:\n\t\ +/set format myformat\n\ +shows the format settings for the mode myformat\n help.set.truncation = \ -Set the max length a displayed value.\n\ +Set the max length of a displayed value:\n\ \n\t\ /set truncation ...\n\ \n\ +Show the current truncation settings:\n\ +\n\t\ +/set truncation []\n\ +\n\ Where is the name of a previously defined feedback mode -- see '/help /set mode'.\n\ Where is an unsigned integer representing a maximum length.\n\ Where is only needed if you wish to fine-tune value truncation length\n\ @@ -571,46 +585,108 @@ /set trunc mymode 80\n\t\ /set truncation mymode 45 expression\n\t\ /set truncation mymode 0 vardecl-modified,replaced\n\n\ -Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n +Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\ +\n\ +The form without shows the truncation settings.\n\ +When the is specified only the truncation settings for that mode are shown.\n\ +Example:\n\t\ +/set truncation myformat\n\ +shows the truncation settings for the mode myformat\n help.set.feedback = \ -Set the feedback mode describing displayed feedback for entered snippets and commands.\n\ +Set the feedback mode describing displayed feedback for entered snippets and commands:\n\ +\n\t\ +/set feedback [-retain] \n\ +\n\ +Retain the current feedback mode for future sessions:\n\ \n\t\ -/set feedback \n\ +/set feedback -retain\n\ +\n\ +Show the feedback mode and list available modes:\n\ +\n\t\ +/set feedback\n\ \n\ Where is the name of a previously defined feedback mode.\n\ You may use just enough letters to make it unique.\n\ User-defined modes can be added, see '/help /set mode'\n\ -Currently defined feedback modes:\n +\n\ +When the -retain option is used, the setting will be used in this and future\n\ +runs of the jshell tool.\n\ +\n\ +The form without or -retain displays the current feedback mode and available modes.\n help.set.mode = \ -Create a user-defined feedback mode, optionally copying from an existing mode.\n\ +Create a user-defined feedback mode, optionally copying from an existing mode:\n\ \n\t\ /set mode [] [-command|-quiet|-delete]\n\ +Retain a user-defined feedback mode for future sessions:\n\ +\n\t\ +/set mode -retain \n\ +\n\ +Delete a user-defined feedback mode:\n\ +\n\t\ +/set mode -delete [-retain] \n\ +\n\ +Show feedback mode settings:\n\ +\n\t\ +/set mode []\n\ \n\ Where is the name of a mode you wish to create.\n\ Where is the name of a previously defined feedback mode.\n\ If is present, its settings are copied to the new mode.\n\ '-command' vs '-quiet' determines if informative/verifying command feedback is displayed.\n\ \n\ -Once the new mode is created, use '/set format' and '/set prompt' to configure it.\n\ -Use '/set feedback' to use the new mode.\n\ +Once the new mode is created, use '/set format', '/set prompt' and '/set truncation'\n\ +to configure it. Use '/set feedback' to use the new mode.\n\ +\n\ +When the -retain option is used, the mode (including its component prompt, format,\n\ +and truncation settings) will be used in this and future runs of the jshell tool.\n\ +When both -retain and -delete are used, the mode is deleted from the current\n\ +and future sessions.\n\ +\n\ +The form without options shows the mode settings.\n\ +When the is specified only the mode settings for that mode are shown.\n\ +Note: the settings for the mode include the settings for prompt, format, and\n\ +truncation -- so these are displayed as well.\n\ +Example:\n\t\ +/set mode myformat\n\ +shows the mode, prompt, format, and truncation settings for the mode myformat\n help.set.prompt = \ -Set the prompts. Both the normal prompt and the continuation-prompt must be set.\n\ +Set the prompts. Both the normal prompt and the continuation-prompt must be set:\n\ \n\t\ /set prompt \"\" \"\"\n\ \n\ +Show the normal prompt and the continuation-prompts:\n\ +\n\t\ +/set prompt []\n\ +\n\ Where is the name of a previously defined feedback mode.\n\ Where and are quoted strings printed as input prompts;\n\ Both may optionally contain '%s' which will be substituted with the next snippet id --\n\ note that what is entered may not be assigned that id, for example it may be an error or command.\n\ -The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n +The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n\ +\n\ +The form without shows the currently set prompts.\n\ +When the is specified only the prompts for that mode are shown.\n\ +Example:\n\t\ +/set prompt myformat\n\ +shows the prompts set for the mode myformat\n help.set.editor =\ -Specify the command to launch for the /edit command.\n\ +Specify the command to launch for the /edit command:\n\ +\n\t\ +/set editor [-retain] [-wait] \n\ \n\t\ -/set editor [-wait] |-default\n\ +/set editor [-retain] [-retain] -default\n\ +\n\ +Retain the current editor setting for future sessions:\n\ +\n\t\ +/set editor -retain\n\ +\n\ +Show the command to launch for the /edit command:\n\ +\n\t\ +/set editor\n\ \n\ The is an operating system dependent string.\n\ The may include space-separated arguments (such as flags)\n\n\ @@ -622,12 +698,29 @@ flags should be used to prevent immediate exit, or the -wait option should be used to\n\ prompt the user to indicate when edit mode should end.\n\n\ Note: while in edit mode no command inputs are seen. After leaving edit mode changes\n\ -to the edited snippets are not seen. +to the edited snippets are not seen.\n\ +\n\ +When the -retain option is used, the setting will be used in this and future\n\ +runs of the jshell tool.\n\ +\n\ +The form without or options shows the editor setting.\n help.set.start =\ -Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\ +Set the start-up configuration -- a sequence of snippets and commands read at start-up:\n\ +\n\t\ +/set start [-retain] \n\ +\n\t\ +/set start [-retain] -default\n\ \n\t\ -/set start |-default|-none\n\ +/set start [-retain] -none\n\ +\n\ +Retain the start-up configuration for future sessions:\n\ +\n\t\ +/set start -retain\n\ +\n\ +Show the start-up setting:\n\ +\n\t\ +/set start\n\ \n\ The contents of the specified become the start-up snippets and commands used\n\ when the /reset or /reload commands are used in this session.\n\ @@ -637,59 +730,14 @@ or commands will be used.\n\ This command is good for testing the start-up settings. To retain them for future\n\ runs of the jshell tool use the command:\n\t\ -/retain start\n - -help.retain.feedback = \ -Retain which feedback mode to use for displayed feedback for entered snippets and commands.\n\ -This feedback mode will be used in this and future sessions of the jshell tool.\n\ -\n\t\ -/retain feedback []\n\ -\n\ -Where is the name of a previously defined feedback mode.\n\ -You may use just enough letters to make it unique.\n\ -If the is not specified, this command retains the current mode (as set\n\ -with the most recent /set feedback or /retain feedback command.)\n\ - -help.retain.mode = \ -Retain the existence and configuration of a user-defined feedback mode.\n\ -This mode will be available in this and future sessions of the jshell tool. -\n\t\ -/retain mode \n\ +/set start -retain\n\ \n\ -Where is the name of a mode you wish to retain.\n\ -The must previously have been created with /set mode and\n\ -configured as desired with /set prompt, /set format, and /set truncation.\n - -help.retain.editor =\ -Retain the command to launch for the /edit command. This command will be invoked when\n\ -the /edit command is used in this and future sessions of the jshell tool.\n\ -\n\t\ -/retain editor [|-default]\n\ +When the -retain option is used, the setting will be used in this and future\n\ +runs of the jshell tool.\n\ \n\ -If is specified, it is an operating system dependent string which\n\ -may include space-separated arguments (such as flags). When /edit is used, the\n\ -temporary file to edit will be appended as the last argument.\n\ -If instead the -default option is specified, the built-in default editor will be used.\n\ -If neither is specified, the editor set in the last /set editor or /retain editor\n\ -command will be used.\n\ -The editor will be retained and used in this and future runs of the jshell tool. - -help.retain.start =\ -Retain the start-up configuration -- a sequence of snippets and commands read\n\ -at start-up.\n\ -\n\t\ -/retain start [|-default|-none]\n\ -\n\ -If is specified, the contents of the specified become the\n\ -start-up snippets\n\ -and commands.\n\ -If instead the -default option is specified, the predefined start-up snippets\n\ -will be the start-up.\n\ -If the -none option is used, the start-up will be empty -- no start-up snippets\n\ -or commands will be used.\n\ -If none of these is specified, the start-up is the last specified in a\n\ -''/set start'' or ''/retain start'' command.\n\ -The start-up will be retained and used when the jshell tool is started or reset +The form without or options shows the start-up setting.\n\ +Note: if the start-up was last set from a file, this is shown with the\n\ +contents of the file followed by a 'set start' command. startup.feedback = \ /set mode verbose -command \n\ @@ -773,6 +821,8 @@ \n\ /set mode silent -quiet \n\ /set prompt silent '-> ' '>> ' \n\ +/set truncation silent 80\n\ +/set truncation silent 1000 varvalue,expression\n\ /set format silent pre '| ' \n\ /set format silent post '%n' \n\ /set format silent errorpre '| ' \n\ diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/CommandCompletionTest.java --- a/langtools/test/jdk/jshell/CommandCompletionTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/CommandCompletionTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -54,7 +54,7 @@ public void testCommand() { assertCompletion("/deb|", false); - assertCompletion("/re|", false, "/reload ", "/reset ", "/retain "); + assertCompletion("/re|", false, "/reload ", "/reset "); assertCompletion("/h|", false, "/help ", "/history "); } @@ -195,34 +195,6 @@ ); } - public void testRetain() throws IOException { - List p1 = listFiles(Paths.get("")); - FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString())); - Collections.sort(p1); - - String[] modes = {"concise ", "normal ", "silent ", "verbose "}; - test(false, new String[] {"--no-startup"}, - a -> assertCompletion(a, "/ret|", false, "/retain "), - a -> assertCompletion(a, "/retain |", false, "editor ", "feedback ", "mode ", "start "), - - // /retain editor - a -> assertCompletion(a, "/retain e|", false, "editor "), - a -> assertCompletion(a, "/retain editor |", false, p1.toArray(new String[p1.size()])), - - // /retain feedback - a -> assertCompletion(a, "/retain fe|", false, "feedback "), - a -> assertCompletion(a, "/retain fe |", false, modes), - - // /retain mode - a -> assertCompletion(a, "/retain mo|", false, "mode "), - a -> assertCompletion(a, "/retain mo |", false, modes), - - // /retain start - a -> assertCompletion(a, "/retain st|", false, "start "), - a -> assertCompletion(a, "/retain st |", false, p1.toArray(new String[p1.size()])) - ); - } - private void createIfNeeded(Path file) throws IOException { if (!Files.exists(file)) Files.createFile(file); diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ExternalEditorTest.java --- a/langtools/test/jdk/jshell/ExternalEditorTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ExternalEditorTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -193,7 +193,6 @@ @Test public void setUnknownEditor() { test( - a -> assertCommand(a, "/set editor", "| The '/set editor' command requires a path argument"), a -> assertCommand(a, "/set editor UNKNOWN", "| Editor set to: UNKNOWN"), a -> assertCommand(a, "int a;", null), a -> assertCommandOutputStartsWith(a, "/ed 1", diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ToolBasicTest.java --- a/langtools/test/jdk/jshell/ToolBasicTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ToolBasicTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -431,12 +431,12 @@ (a) -> assertMethod(a, "void f() {}", "()V", "f"), (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"), (a) -> assertCommand(a, "/save " + startUpFile.toString(), null), - (a) -> assertCommand(a, "/retain start " + startUpFile.toString(), null) + (a) -> assertCommand(a, "/set start -retain " + startUpFile.toString(), null) ); Path unknown = compiler.getPath("UNKNOWN"); test( - (a) -> assertCommandOutputStartsWith(a, "/retain start " + unknown.toString(), - "| File '" + unknown + "' for '/retain start' is not found.") + (a) -> assertCommandOutputStartsWith(a, "/set start -retain " + unknown.toString(), + "| File '" + unknown + "' for '/set start' is not found.") ); test(false, new String[0], (a) -> { diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ToolCommandOptionTest.java --- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 8157395 8157393 8157517 8158738 8167128 + * @bug 8157395 8157393 8157517 8158738 8167128 8163840 * @summary Tests of jshell comand options, and undoing operations * @modules jdk.jshell/jdk.internal.jshell.tool * @build ToolCommandOptionTest ReplToolTesting @@ -128,46 +128,73 @@ (a) -> assertCommand(a, "/set editor prog", "| Editor set to: prog"), (a) -> assertCommand(a, "/set editor prog -default", - "| Editor set to: prog"), + "| Editor set to: prog -default"), + (a) -> assertCommand(a, "/set editor", + "| /set editor prog -default"), (a) -> assertCommand(a, "/se ed prog -furball", - "| Editor set to: prog"), + "| Editor set to: prog -furball"), + (a) -> assertCommand(a, "/set editor", + "| /set editor prog -furball"), (a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4", - "| Editor set to: prog"), + "| Editor set to: prog arg1 -furball arg3 -default arg4"), + (a) -> assertCommand(a, "/set editor", + "| /set editor prog arg1 -furball arg3 -default arg4"), (a) -> assertCommand(a, "/set editor -default", - ""), + "| Editor set to: -default"), (a) -> assertCommand(a, "/se edi -def", - ""), + "| Editor set to: -default"), (a) -> assertCommand(a, "/set editor", - "| The '/set editor' command requires a path argument") + "| /set editor -default") ); } public void retainEditorTest() { test( - (a) -> assertCommand(a, "/retain editor -furball", - "| Unknown option: -furball -- /retain editor -furball"), - (a) -> assertCommand(a, "/retain editor -furball prog", - "| Unknown option: -furball -- /retain editor -furball prog"), - (a) -> assertCommand(a, "/retain editor -furball -mattress", - "| Unknown option: -furball -mattress -- /retain editor -furball -mattress"), - (a) -> assertCommand(a, "/retain editor -default prog", - "| Specify -default option or program, not both -- /retain editor -default prog"), - (a) -> assertCommand(a, "/retain editor -default -wait", - "| -wait applies to external editors, cannot be used with -default"), - (a) -> assertCommand(a, "/retain editor prog", - "| Editor set to: prog"), - (a) -> assertCommand(a, "/retain editor prog -default", - "| Editor set to: prog"), - (a) -> assertCommand(a, "/ret ed prog -furball", - "| Editor set to: prog"), - (a) -> assertCommand(a, "/retain editor prog arg1 -furball arg3 -default arg4", - "| Editor set to: prog"), - (a) -> assertCommand(a, "/retain editor -default", - ""), - (a) -> assertCommand(a, "/reta edi -def", - ""), - (a) -> assertCommand(a, "/retain editor", - "") + (a) -> assertCommand(a, "/set editor -retain -furball", + "| Unknown option: -furball -- /set editor -retain -furball"), + (a) -> assertCommand(a, "/set editor -retain -furball prog", + "| Unknown option: -furball -- /set editor -retain -furball prog"), + (a) -> assertCommand(a, "/set editor -retain -furball -mattress", + "| Unknown option: -furball -mattress -- /set editor -retain -furball -mattress"), + (a) -> assertCommand(a, "/set editor -retain -default prog", + "| Specify -default option or program, not both -- /set editor -retain -default prog"), + (a) -> assertCommand(a, "/set editor -retain -wait", + "| -wait applies to external editors"), + (a) -> assertCommand(a, "/set editor -retain -default -wait", + "| -wait applies to external editors"), + (a) -> assertCommand(a, "/set editor -retain prog", + "| Editor set to: prog\n" + + "| Editor setting retained: prog"), + (a) -> assertCommand(a, "/set editor", + "| /set editor -retain prog"), + (a) -> assertCommand(a, "/se ed other", + "| Editor set to: other"), + (a) -> assertCommand(a, "/set editor", + "| /set editor -retain prog\n" + + "| /set editor other"), + (a) -> assertCommand(a, "/set editor -retain prog -default", + "| Editor set to: prog -default\n" + + "| Editor setting retained: prog -default"), + (a) -> assertCommand(a, "/set editor", + "| /set editor -retain prog -default"), + (a) -> assertCommand(a, "/se ed -retain prog -furball", + "| Editor set to: prog -furball\n" + + "| Editor setting retained: prog -furball"), + (a) -> assertCommand(a, "/set editor -retain prog arg1 -furball arg3 -default arg4", + "| Editor set to: prog arg1 -furball arg3 -default arg4\n" + + "| Editor setting retained: prog arg1 -furball arg3 -default arg4"), + (a) -> assertCommand(a, "/set editor", + "| /set editor -retain prog arg1 -furball arg3 -default arg4"), + (a) -> assertCommand(a, "/set editor -retain -default", + "| Editor set to: -default\n" + + "| Editor setting retained: -default"), + (a) -> assertCommand(a, "/set editor", + "| /set editor -retain -default"), + (a) -> assertCommand(a, "/se e -ret -def", + "| Editor set to: -default\n" + + "| Editor setting retained: -default"), + (a) -> assertCommand(a, "/set editor -retain", + "| Editor setting retained: -default") ); } @@ -182,45 +209,56 @@ (a) -> assertCommand(a, "/set start -furball -mattress", "| Unknown option: -furball -mattress -- /set start -furball -mattress"), (a) -> assertCommand(a, "/set start foo -default", - "| Specify either one option or a startup file name -- /set start foo -default"), + "| Specify no more than one of -default, -none, or a startup file name -- /set start foo -default"), (a) -> assertCommand(a, "/set start frfg", "| File 'frfg' for '/set start' is not found."), (a) -> assertCommand(a, "/set start -default", ""), + (a) -> assertCommand(a, "/set start", + "| /set start -default"), (a) -> assertCommand(a, "/se sta -no", ""), (a) -> assertCommand(a, "/set start", - "| Specify either one option or a startup file name -- /set start") + "| /set start -none") ); } public void retainStartTest() { test( - (a) -> assertCommand(a, "/retain start -furball", - "| Unknown option: -furball -- /retain start -furball"), - (a) -> assertCommand(a, "/retain start -furball pyle", - "| Unknown option: -furball -- /retain start -furball pyle"), - (a) -> assertCommand(a, "/ret st pyle -furball", - "| Unknown option: -furball -- /retain st pyle -furball"), - (a) -> assertCommand(a, "/retain start -furball -mattress", - "| Unknown option: -furball -mattress -- /retain start -furball -mattress"), - (a) -> assertCommand(a, "/retain start foo -default", - "| Specify either one option or a startup file name -- /retain start foo -default"), - (a) -> assertCommand(a, "/retain start frfg", - "| File 'frfg' for '/retain start' is not found."), - (a) -> assertCommand(a, "/retain start -default", + (a) -> assertCommand(a, "/set start -retain -furball", + "| Unknown option: -furball -- /set start -retain -furball"), + (a) -> assertCommand(a, "/set start -retain -furball pyle", + "| Unknown option: -furball -- /set start -retain -furball pyle"), + (a) -> assertCommand(a, "/se st -re pyle -furball", + "| Unknown option: -furball -- /set st -re pyle -furball"), + (a) -> assertCommand(a, "/set start -retain -furball -mattress", + "| Unknown option: -furball -mattress -- /set start -retain -furball -mattress"), + (a) -> assertCommand(a, "/set start -retain foo -default", + "| Specify no more than one of -default, -none, or a startup file name -- /set start -retain foo -default"), + (a) -> assertCommand(a, "/set start -retain -default foo", + "| Specify no more than one of -default, -none, or a startup file name -- /set start -retain -default foo"), + (a) -> assertCommand(a, "/set start -retain frfg", + "| File 'frfg' for '/set start' is not found."), + (a) -> assertCommand(a, "/set start -retain -default", ""), - (a) -> assertCommand(a, "/ret sta -no", + (a) -> assertCommand(a, "/set start", + "| /set start -retain -default"), + (a) -> assertCommand(a, "/set sta -no", ""), - (a) -> assertCommand(a, "/retain start", - "") + (a) -> assertCommand(a, "/set start", + "| /set start -retain -default\n" + + "| /set start -none"), + (a) -> assertCommand(a, "/se st -ret", + ""), + (a) -> assertCommand(a, "/se sta", + "| /set start -retain -none") ); } public void setModeTest() { test( - (a) -> assertCommandOutputStartsWith(a, "/set mode", - "| Missing the feedback mode"), + (a) -> assertCommandOutputContains(a, "/set mode", + "| /set format verbose unresolved"), (a) -> assertCommandOutputStartsWith(a, "/set mode *", "| Expected a feedback mode name: *"), (a) -> assertCommandOutputStartsWith(a, "/set mode -quiet", @@ -229,11 +267,13 @@ "| Expected a feedback mode name: *"), (a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing", "| Unexpected arguments at end of command: thing"), - (a) -> assertCommand(a, "/set mode mymode", + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode", + "| To create a new mode either the -command or the -quiet option must be used"), + (a) -> assertCommand(a, "/set mode mymode -command", "| Created new feedback mode: mymode"), (a) -> assertCommand(a, "/set mode mymode -delete", ""), - (a) -> assertCommand(a, "/set mode mymode normal", + (a) -> assertCommand(a, "/set mode mymode normal -command", "| Created new feedback mode: mymode"), (a) -> assertCommand(a, "/set mode -del mymode", ""), @@ -245,18 +285,33 @@ "| Conflicting options"), (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d", "| No feedback mode named: mymode"), - (a) -> assertCommandOutputStartsWith(a, "/set mode normal", - "| Not valid with a predefined mode: normal"), + (a) -> assertCommandOutputStartsWith(a, "/set mode normal -c", + "| Mode to be created already exists: normal"), (a) -> assertCommand(a, "/se mo -c mymode", "| Created new feedback mode: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode", + "| /set mode mymode -command"), (a) -> assertCommand(a, "/set feedback mymode", "| Feedback mode: mymode"), + (a) -> assertCommand(a, "/se fe", + "| /set feedback mymode\n" + + "| \n" + + "| Available feedback modes:\n" + + "| concise\n" + + "| mymode\n" + + "| normal\n" + + "| silent\n" + + "| verbose"), (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete", "| The current feedback mode 'mymode' cannot be deleted"), (a) -> assertCommand(a, "/set feedback no", "| Feedback mode: normal"), (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete", ""), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode", + "| To create a new mode either the -command or the -quiet option must be used -- \n" + + "| Does not match any current feedback mode: mymode -- /set mode mymode\n" + + "| Available feedback modes:"), (a) -> assertCommandCheckOutput(a, "/set feedback", (s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s)) ); @@ -272,8 +327,20 @@ ""), (a) -> assertCommand(a, "45", "blurb"), - (a) -> assertCommand(a, "/set mode mymode normal", + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode normal", + "| To create a new mode either the -command or the -quiet option must be used"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command normal", + "| Mode to be created already exists: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete", + "| The current feedback mode 'mymode' cannot be deleted, use '/set feedback' first"), + (a) -> assertCommand(a, "/set feedback normal", + "| Feedback mode: normal"), + (a) -> assertCommand(a, "/set mode mymode -delete", + ""), + (a) -> assertCommand(a, "/set mode mymode -command normal", "| Created new feedback mode: mymode"), + (a) -> assertCommand(a, "/set feedback mymode", + "| Feedback mode: mymode"), (a) -> assertCommandOutputContains(a, "45", " ==> 45") ); @@ -281,67 +348,89 @@ public void retainModeTest() { test( - (a) -> assertCommandOutputStartsWith(a, "/retain mode", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain", "| Missing the feedback mode"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode *", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain *", "| Expected a feedback mode name: *"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode amode normal", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain amode normal", "| Unexpected arguments at end of command: normal"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode", - "| Does not match any current feedback mode: mymode"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode -delete", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode", "| No feedback mode named: mymode"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode -d mymode", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode -delete", + "| No feedback mode named: mymode"), + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain -d mymode", "| No feedback mode named: mymode"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode normal", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain normal", "| Not valid with a predefined mode: normal"), - (a) -> assertCommand(a, "/set mode mymode verbose", + (a) -> assertCommand(a, "/set mode mymode verbose -command", "| Created new feedback mode: mymode"), - (a) -> assertCommand(a, "/retain mode mymode", + (a) -> assertCommand(a, "/set mode -retain mymode", ""), (a) -> assertCommand(a, "/set mode mymode -delete", ""), - (a) -> assertCommand(a, "/retain mode mymode -delete", + (a) -> assertCommand(a, "/set mode -retain mymode -delete", ""), - (a) -> assertCommand(a, "/set mode kmode normal", + (a) -> assertCommand(a, "/set mode kmode normal -command", "| Created new feedback mode: kmode"), - (a) -> assertCommand(a, "/retain mode kmode", + (a) -> assertCommand(a, "/set mode -retain kmode", ""), (a) -> assertCommand(a, "/set mode kmode -delete", ""), - (a) -> assertCommand(a, "/set mode tmode normal", + (a) -> assertCommand(a, "/set mode tmode normal -command", "| Created new feedback mode: tmode"), - (a) -> assertCommandOutputStartsWith(a, "/retain feedback tmode", - "| '/retain feedback ' requires that is predefined or has been retained with '/retain mode'"), + (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode", + "| '/set feedback -retain ' requires that is predefined or has been retained with '/set mode -retain'"), (a) -> assertCommand(a, "/set format tmode display 'YES'", ""), (a) -> assertCommand(a, "/set feedback tmode", "| Feedback mode: tmode"), (a) -> assertCommand(a, "45", "YES"), - (a) -> assertCommand(a, "/retain mode tmode", + (a) -> assertCommand(a, "/set mode -retain tmode", ""), - (a) -> assertCommand(a, "/retain feedback tmode", + (a) -> assertCommand(a, "/set feedback -retain tmode", "| Feedback mode: tmode"), (a) -> assertCommand(a, "/set format tmode display 'blurb'", ""), + (a) -> assertCommand(a, "/set format tmode display", + "| /set format tmode display \"blurb\""), + (a) -> assertCommandOutputContains(a, "/set mode tmode", + "| /set format tmode display \"YES\""), (a) -> assertCommand(a, "45", "blurb") ); test( + (a) -> assertCommand(a, "/set format tmode display", + "| /set format tmode display \"YES\""), + (a) -> assertCommandOutputContains(a, "/set mode tmode", + "| /set format tmode display \"YES\""), (a) -> assertCommand(a, "45", "YES"), (a) -> assertCommand(a, "/set feedback kmode", "| Feedback mode: kmode"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete", + (a) -> assertCommand(a, "/set feedback", + "| /set feedback -retain tmode\n" + + "| /set feedback kmode\n" + + "| \n" + + "| Retained feedback modes:\n" + + "| kmode\n" + + "| tmode\n" + + "| Available feedback modes:\n" + + "| concise\n" + + "| kmode\n" + + "| normal\n" + + "| silent\n" + + "| tmode\n" + + "| verbose"), + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete", "| The current feedback mode 'kmode' cannot be deleted"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode tmode -delete", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain tmode -delete", "| The retained feedback mode 'tmode' cannot be deleted"), - (a) -> assertCommand(a, "/retain feedback normal", + (a) -> assertCommand(a, "/set feedback -retain normal", "| Feedback mode: normal"), - (a) -> assertCommand(a, "/retain mode tmode -delete", + (a) -> assertCommand(a, "/set mode -retain tmode -delete", ""), - (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete", "") ); test( diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ToolFormatTest.java --- a/langtools/test/jdk/jshell/ToolFormatTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ToolFormatTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 + * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 * @summary Tests for output customization * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -33,10 +33,17 @@ * @build KullaTesting TestingInputStream toolbox.ToolBox Compiler * @run testng ToolFormatTest */ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; @Test public class ToolFormatTest extends ReplToolTesting { @@ -81,6 +88,58 @@ } } + public void testSetFormatOverride() { + test( + (a) -> assertCommand(a, "/set mode tm -c", "| Created new feedback mode: tm"), + (a) -> assertCommand(a, "/se fo tm x \"aaa\"", ""), + (a) -> assertCommand(a, "/se fo tm x \"bbb\" class,method-added", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"bbb\" class,method-added"), + (a) -> assertCommand(a, "/se fo tm x \"ccc\" class,method-added,modified", ""), + (a) -> assertCommand(a, "/se fo tm x \"ddd\" class,method-added", ""), + (a) -> assertCommand(a, "/se fo tm x \"eee\" method-added", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"ccc\" class,method-added,modified\n" + + "| /set format tm x \"ddd\" class,method-added\n" + + "| /set format tm x \"eee\" method-added"), + (a) -> assertCommand(a, "/se fo tm x \"EEE\" method-added,replaced", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"ccc\" class,method-added,modified\n" + + "| /set format tm x \"ddd\" class,method-added\n" + + "| /set format tm x \"EEE\" method-added,replaced"), + (a) -> assertCommand(a, "/se fo tm x \"fff\" method-added,replaced-ok", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"ccc\" class,method-added,modified\n" + + "| /set format tm x \"ddd\" class,method-added\n" + + "| /set format tm x \"EEE\" method-added,replaced\n" + + "| /set format tm x \"fff\" method-added,replaced-ok"), + (a) -> assertCommand(a, "/se fo tm x \"ggg\" method-ok", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"ccc\" class,method-added,modified\n" + + "| /set format tm x \"ddd\" class,method-added\n" + + "| /set format tm x \"EEE\" method-added,replaced\n" + + "| /set format tm x \"ggg\" method-ok"), + (a) -> assertCommand(a, "/se fo tm x \"hhh\" method", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"ccc\" class,method-added,modified\n" + + "| /set format tm x \"ddd\" class,method-added\n" + + "| /set format tm x \"hhh\" method"), + (a) -> assertCommand(a, "/se fo tm x \"iii\" method,class", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"aaa\" \n" + + "| /set format tm x \"iii\" class,method"), + (a) -> assertCommand(a, "/se fo tm x \"jjj\"", ""), + (a) -> assertCommand(a, "/se fo tm x", + "| /set format tm x \"jjj\"") + ); + } + public void testSetFormatSelector() { List tests = new ArrayList<>(); tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet", @@ -167,8 +226,14 @@ (a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""), (a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""), (a) -> assertCommand(a, "/set truncation test 20", ""), + (a) -> assertCommand(a, "/set truncation test", "| /set truncation test 20"), + (a) -> assertCommandOutputContains(a, "/set truncation", "/set truncation test 20"), (a) -> assertCommand(a, "/set trunc test 10 varvalue", ""), (a) -> assertCommand(a, "/set trunc test 3 assignment", ""), + (a) -> assertCommandOutputContains(a, "/set truncation", + "/set truncation test 10 varvalue"), + (a) -> assertCommandOutputContains(a, "/set truncation test", + "/set truncation test 10 varvalue"), (a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."), (a) -> assertCommand(a, "r", "String:\"ABACA ..."), (a) -> assertCommand(a, "r=s", "String:\"AB") @@ -201,6 +266,45 @@ ); } + public void testPrompt() { + test( + (a) -> assertCommand(a, "/set mode tp -quiet", "| Created new feedback mode: tp"), + (a) -> assertCommand(a, "/set prompt tp 'aaa' 'bbb'", ""), + (a) -> assertCommand(a, "/set prompt tp", + "| /set prompt tp \"aaa\" \"bbb\""), + (a) -> assertCommandOutputContains(a, "/set prompt", + "| /set prompt tp \"aaa\" \"bbb\""), + (a) -> assertCommand(a, "/set mode -retain tp", ""), + (a) -> assertCommand(a, "/set prompt tp 'ccc' 'ddd'", ""), + (a) -> assertCommand(a, "/set prompt tp", + "| /set prompt tp \"ccc\" \"ddd\""), + (a) -> assertCommandCheckOutput(a, "/set mode tp", + (s) -> { + try { + BufferedReader rdr = new BufferedReader(new StringReader(s)); + assertEquals(rdr.readLine(), "| /set mode tp -quiet", + "| /set mode tp -quiet"); + assertEquals(rdr.readLine(), "| /set prompt tp \"aaa\" \"bbb\"", + "| /set prompt tp \"aaa\" \"bbb\""); + String l = rdr.readLine(); + while (l.startsWith("| /set format tp ")) { + l = rdr.readLine(); + } + assertEquals(l, "| /set mode -retain tp", + "| /set mode -retain tp"); + assertEquals(rdr.readLine(), "| ", + "| "); + assertEquals(rdr.readLine(), "| /set mode tp -quiet", + "| /set mode tp -quiet"); + assertEquals(rdr.readLine(), "| /set prompt tp \"ccc\" \"ddd\"", + "| /set prompt tp \"ccc\" \"ddd\""); + } catch (IOException ex) { + fail("threw " + ex); + } + }) + ); + } + public void testShowFeedbackModes() { test( (a) -> assertCommandOutputContains(a, "/set feedback", "normal") @@ -216,7 +320,8 @@ (a) -> assertCommand(a, "/se fee nmq2", ""), (a) -> assertCommand(a, "/set mode nmc -command normal", ""), (a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"), - (a) -> assertCommandOutputStartsWith(a, "/set mode nm", "| Created new feedback mode: nm"), + (a) -> assertCommandOutputStartsWith(a, "/set mode nm -command", + "| Created new feedback mode: nm"), (a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm"), (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal") ); @@ -231,37 +336,35 @@ test( (a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo", "| Does not match any current feedback mode: foo"), - (a) -> assertCommandOutputStartsWith(a, "/set mode tee flurb", + (a) -> assertCommandOutputStartsWith(a, "/set mode tee -quiet flurb", "| Does not match any current feedback mode: flurb"), - (a) -> assertCommandOutputStartsWith(a, "/set mode tee", + (a) -> assertCommandOutputStartsWith(a, "/set mode -command tee", "| Created new feedback mode: tee"), - (a) -> assertCommandOutputStartsWith(a, "/set mode verbose", - "| Not valid with a predefined mode: verbose"), + (a) -> assertCommandOutputStartsWith(a, "/set mode verbose -command", + "| Mode to be created already exists: verbose"), (a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal", "| Created new feedback mode: te"), (a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""), (a) -> assertCommandOutputStartsWith(a, "/set feedback te", ""), - (a) -> assertCommandOutputStartsWith(a, "/set ", - "ERROR: The '/set' command requires a sub-command"), (a) -> assertCommandOutputStartsWith(a, "/set xyz", "ERROR: Invalid '/set' argument: xyz"), (a) -> assertCommandOutputStartsWith(a, "/set f", "ERROR: Ambiguous sub-command argument to '/set': f"), (a) -> assertCommandOutputStartsWith(a, "/set feedback", - "ERROR: Missing the feedback mode"), + "| /set feedback te"), (a) -> assertCommandOutputStartsWith(a, "/set feedback xyz", "ERROR: Does not match any current feedback mode"), - (a) -> assertCommandOutputStartsWith(a, "/set format", - "ERROR: Missing the feedback mode"), + (a) -> assertCommandOutputStartsWith(a, "/set feed", + "| /set feedback te"), (a) -> assertCommandOutputStartsWith(a, "/set format xyz", "ERROR: Does not match any current feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set format t", "ERROR: Matches more then one current feedback mode: t"), - (a) -> assertCommandOutputStartsWith(a, "/set format te", - "ERROR: Missing the field name"), + (a) -> assertCommandOutputStartsWith(a, "/set format qqq", + "ERROR: Does not match any current feedback mode: qqq"), (a) -> assertCommandOutputStartsWith(a, "/set format te fld", - "ERROR: Expected format missing"), + "ERROR: Expected a field name:"), (a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa", "ERROR: Format 'aaa' must be quoted"), (a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' frog", @@ -274,30 +377,28 @@ "ERROR: Different selector kinds in same sections of"), (a) -> assertCommandOutputStartsWith(a, "/set trunc te 20x", "ERROR: Truncation length must be an integer: 20x"), - (a) -> assertCommandOutputStartsWith(a, "/set trunc te", - "ERROR: Expected truncation length"), + (a) -> assertCommandOutputStartsWith(a, "/set trunc qaz", + "ERROR: Does not match any current feedback mode: qaz -- /set trunc qaz"), (a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added", "ERROR: Different selector kinds in same sections of"), - (a) -> assertCommandOutputStartsWith(a, "/set mode", + (a) -> assertCommandOutputContains(a, "/set mode", + "| /set truncation verbose"), + (a) -> assertCommandOutputStartsWith(a, "/set mode -command", "ERROR: Missing the feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y", "ERROR: Does not match any current feedback mode"), (a) -> assertCommandOutputStartsWith(a, "/set prompt", - "ERROR: Missing the feedback mode"), + "| /set prompt"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te", - "ERROR: Expected format missing"), + "| /set prompt te "), (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz", "ERROR: Format 'aaa' must be quoted"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz", "ERROR: Format 'xyz' must be quoted"), - (a) -> assertCommandOutputStartsWith(a, "/set prompt", - "ERROR: Missing the feedback mode"), - (a) -> assertCommandOutputStartsWith(a, "/set prompt te", - "ERROR: Expected format missing"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa", "ERROR: Format 'aaa' must be quoted"), (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa'", - "ERROR: Expected format missing"), + "ERROR: Continuation prompt required"), (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal") ); diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ToolLocaleMessageTest.java --- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -106,10 +106,11 @@ (a) -> assertCommandOK(a, "/set feedback test", "test"), (a) -> assertCommandFail(a, "/list zebra"), - (a) -> assertCommandFail(a, "/set editor", "/set editor"), + (a) -> assertCommandFail(a, "/set editor -rot", "/set editor -rot"), (a) -> assertCommandFail(a, "/set snowball", "/set", "snowball"), - (a) -> assertCommandFail(a, "/set", "/set", "/help"), - (a) -> assertCommandFail(a, "/set f", "feedback"), + (a) -> assertCommandOK(a, "/set", "| /set feedback test", "verbose"), + (a) -> assertCommandFail(a, "/set f", "/set"), + (a) -> assertCommandOK(a, "/set fe", "| /set feedback test"), (a) -> assertCommandFail(a, "/classpath", "/classpath"), (a) -> assertCommandFail(a, "/help rabbits", "rabbits"), (a) -> assertCommandFail(a, "/drop"), @@ -164,27 +165,20 @@ (a) -> assertCommandOK(a, "/set format te errorpre 'ERROR: '"), (a) -> assertCommandOK(a, "/set feedback te"), - (a) -> assertCommandFail(a, "/set "), (a) -> assertCommandFail(a, "/set xyz", "xyz"), (a) -> assertCommandFail(a, "/set f", "/set", "f"), - (a) -> assertCommandFail(a, "/set feedback"), (a) -> assertCommandFail(a, "/set feedback xyz"), - (a) -> assertCommandFail(a, "/set format"), (a) -> assertCommandFail(a, "/set format xyz"), (a) -> assertCommandFail(a, "/set format t"), - (a) -> assertCommandFail(a, "/set format te"), (a) -> assertCommandFail(a, "/set format te fld"), (a) -> assertCommandFail(a, "/set format te fld aaa", "aaa"), (a) -> assertCommandFail(a, "/set format te fld 'aaa' frog"), (a) -> assertCommandFail(a, "/set format te fld 'aaa' import-frog"), (a) -> assertCommandFail(a, "/set format te fld 'aaa' import-import"), (a) -> assertCommandFail(a, "/set format te fld 'aaa' import,added"), - (a) -> assertCommandFail(a, "/set mode"), (a) -> assertCommandFail(a, "/set mode x xyz"), (a) -> assertCommandFail(a, "/set mode x -quiet y"), (a) -> assertCommandFail(a, "/set mode tee -command foo", "foo"), - (a) -> assertCommandFail(a, "/set prompt"), - (a) -> assertCommandFail(a, "/set prompt te"), (a) -> assertCommandFail(a, "/set prompt te aaa xyz", "aaa"), (a) -> assertCommandFail(a, "/set prompt te 'aaa' xyz", "xyz"), (a) -> assertCommandFail(a, "/set prompt te aaa"), diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ToolRetainTest.java --- a/langtools/test/jdk/jshell/ToolRetainTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ToolRetainTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 8157200 + * @bug 8157200 8163840 * @summary Tests of what information is retained across jshell tool runs * @modules jdk.jshell/jdk.internal.jshell.tool * @build ToolRetainTest ReplToolTesting @@ -41,10 +41,12 @@ (a) -> assertCommand(a, "/set feedback trm", ""), (a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""), (a) -> assertCommand(a, "int x = 45", "x:45"), - (a) -> assertCommand(a, "/retain mode trm", ""), + (a) -> assertCommand(a, "/set mode -retain trm", ""), (a) -> assertCommand(a, "/exit", "") ); test( + (a) -> assertCommandOutputContains(a, "/set mode trm", + "/set format trm display \"{name}:{value}\""), (a) -> assertCommand(a, "/set feedback trm", ""), (a) -> assertCommand(a, "int x = 45", "x:45") ); @@ -53,21 +55,25 @@ public void testRetain2Mode() { test( (a) -> assertCommand(a, "/set mode trm1 -quiet", "| Created new feedback mode: trm1"), - (a) -> assertCommand(a, "/retain mode trm1", ""), - (a) -> assertCommand(a, "/retain feedback trm1", ""), + (a) -> assertCommand(a, "/set mode -retain trm1", ""), + (a) -> assertCommand(a, "/set feedback -retain trm1", ""), (a) -> assertCommand(a, "/set format trm1 display '{name}:{value}'", ""), (a) -> assertCommand(a, "int x = 66", "x:66"), - (a) -> assertCommand(a, "/retain mode trm1", ""), + (a) -> assertCommand(a, "/set mode -retain trm1", ""), (a) -> assertCommand(a, "/exit", "") ); test( (a) -> assertCommand(a, "/set mode trm2 -quiet", ""), (a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""), (a) -> assertCommand(a, "int x = 45", "x:45"), - (a) -> assertCommand(a, "/retain mode trm2", ""), + (a) -> assertCommand(a, "/set mode -retain trm2", ""), (a) -> assertCommand(a, "/exit", "") ); test( + (a) -> assertCommandOutputContains(a, "/set mode trm1", + "/set format trm1 display \"{name}:{value}\""), + (a) -> assertCommand(a, "/set format trm2 display", + "| /set format trm2 display \"{name}={value}\""), (a) -> assertCommand(a, "int x = 99", "x:99"), (a) -> assertCommand(a, "/set feedback trm2", ""), (a) -> assertCommand(a, "int z = 77", "z=77") @@ -76,31 +82,48 @@ public void testRetainFeedback() { test( - (a) -> assertCommand(a, "/retain feedback verbose", "| Feedback mode: verbose"), + (a) -> assertCommand(a, "/set feedback -retain verbose", "| Feedback mode: verbose"), (a) -> assertCommand(a, "/exit", "") ); test( + (a) -> assertCommandOutputStartsWith(a, "/set feedback", + "| /set feedback -retain verbose\n" + + "| \n" + + "| "), (a) -> assertCommandOutputContains(a, "int h =8", "| created variable h : int") ); } public void testRetainFeedbackBlank() { + String feedbackOut = + "| /set feedback -retain verbose\n" + + "| \n" + + "| Available feedback modes:\n" + + "| concise\n" + + "| normal\n" + + "| silent\n" + + "| verbose"; test( (a) -> assertCommand(a, "/set feedback verbose", "| Feedback mode: verbose"), - (a) -> assertCommand(a, "/retain feedback", ""), + (a) -> assertCommand(a, "/set feedback -retain", ""), + (a) -> assertCommand(a, "/set feedback", feedbackOut), (a) -> assertCommand(a, "/exit", "") ); test( + (a) -> assertCommand(a, "/set feedback", feedbackOut), (a) -> assertCommandOutputContains(a, "int qw = 5", "| created variable qw : int") ); } public void testRetainEditor() { test( - (a) -> assertCommand(a, "/retain editor nonexistent", "| Editor set to: nonexistent"), + (a) -> assertCommand(a, "/set editor -retain nonexistent", + "| Editor set to: nonexistent\n" + + "| Editor setting retained: nonexistent"), (a) -> assertCommand(a, "/exit", "") ); test( + (a) -> assertCommand(a, "/set editor", "| /set editor -retain nonexistent"), (a) -> assertCommandOutputContains(a, "int h =8", ""), (a) -> assertCommandOutputContains(a, "/edit h", "Edit Error:") ); @@ -109,7 +132,7 @@ public void testRetainEditorBlank() { test( (a) -> assertCommand(a, "/set editor nonexistent", "| Editor set to: nonexistent"), - (a) -> assertCommand(a, "/retain editor", ""), + (a) -> assertCommand(a, "/set editor -retain", "| Editor setting retained: nonexistent"), (a) -> assertCommand(a, "/exit", "") ); test( @@ -120,22 +143,25 @@ public void testRetainModeNeg() { test( - (a) -> assertCommandOutputStartsWith(a, "/retain mode verbose", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain verbose", "| Not valid with a predefined mode"), - (a) -> assertCommandOutputStartsWith(a, "/retain mode ????", + (a) -> assertCommandOutputStartsWith(a, "/set mode -retain ????", "| Expected a feedback mode name: ????") ); } public void testRetainFeedbackNeg() { test( - (a) -> assertCommandOutputStartsWith(a, "/retain feedback babble1", + (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain babble1", "| Does not match any current feedback mode"), - (a) -> assertCommand(a, "/set mode trfn", + (a) -> assertCommandOutputStartsWith(a, "/set mode trfn", + "| To create a new mode either the -command or the -quiet option must be used -- \n" + + "| Does not match any current feedback mode: trfn -- /set mode trfn"), + (a) -> assertCommand(a, "/set mode trfn -command", "| Created new feedback mode: trfn"), - (a) -> assertCommandOutputContains(a, "/retain feedback trfn", + (a) -> assertCommandOutputContains(a, "/set feedback -retain trfn", "is predefined or has been retained"), - (a) -> assertCommandOutputStartsWith(a, "/retain feedback !!!!", + (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain !!!!", "| Expected a feedback mode name: !!!!") ); } diff -r 3f9c491b05aa -r cb3d04878117 langtools/test/jdk/jshell/ToolSimpleTest.java --- a/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Oct 19 16:58:09 2016 -0700 +++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Thu Oct 20 12:53:11 2016 -0700 @@ -193,8 +193,8 @@ "| '/save' requires a filename argument."), (a) -> assertCommand(a, "/open", "| '/open' requires a filename argument."), - (a) -> assertCommand(a, "/set start", - "| Specify either one option or a startup file name -- /set start") + (a) -> assertCommandOutputStartsWith(a, "/drop", + "| In the /drop argument, please specify an import, variable, method, or class to drop.") ); }