8163840: jshell tool: provide way to display configuration settings
Reviewed-by: jlahoda
--- 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<String> 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);
}
}
--- 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<String> 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<String> 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("<init>", "")).restoreEncodedModes(encoded);
}
@@ -177,6 +179,15 @@
selectorMap.put(e.name().toLowerCase(Locale.US), e);
}
+ private static class SelectorSets {
+ Set<FormatCase> cc;
+ Set<FormatAction> ca;
+ Set<FormatWhen> cw;
+ Set<FormatResolve> cr;
+ Set<FormatUnresolved> cu;
+ Set<FormatErrors> 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<Setting> settings = cases.computeIfAbsent(field, k -> new ArrayList<>());
+ private void add(String field, Setting ing) {
+ List<Setting> 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;
+
+ <E extends Enum<E>> Set<E> unpackEnumbits(E[] values) {
+ Set<E> 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<E extends Enum<E> & Selector<E>> {
SelectorCollector<E> 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 <E extends Enum<E>> void selectorToString(StringBuilder sb, Set<E> 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<CharSequence, StringJoiner, String>() {
+ @Override
+ public BiConsumer<StringJoiner, CharSequence> accumulator() {
+ return StringJoiner::add;
+ }
+
+ @Override
+ public Supplier<StringJoiner> supplier() {
+ return () -> new StringJoiner(",", (sb.length() == 0)? "" : "-", "")
+ .setEmptyValue("");
+ }
+
+ @Override
+ public BinaryOperator<StringJoiner> combiner() {
+ return StringJoiner::merge;
+ }
+
+ @Override
+ public Function<StringJoiner, String> finisher() {
+ return StringJoiner::toString;
+ }
+
+ @Override
+ public Set<Characteristics> 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<Mode.Setting> 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 <mode> "<prompt>" "<continuation-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<String> 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 <mode>
- boolean setFeedback() {
+ // For /set format <mode> <field> "<format>" <selector>...
+ 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 <mode> "<format>" <selector>...
- 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 <mode> <length> <selector>...
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 <mode>
+ boolean setFeedback(Consumer<String> 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<String> itr = Arrays.asList(ms).iterator();
+ Iterator<String> itr = encodedModeIterator(allEncoded);
while (itr.hasNext()) {
// Reconstruct the encoded mode
Mode m = new Mode(itr);
@@ -934,50 +1185,60 @@
}
}
+ Iterator<String> 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<SelectorList> 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<FormatCase> 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);
--- 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<String> 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 <editor-command-line>>
- boolean setEditor(ArgTokenizer at, boolean argsRequired) {
- at.allowedOptions("-default", "-wait");
- String prog = at.next();
- List<String> 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<String> 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<String> elems = Arrays.stream(ed.cmd);
+ if (ed.wait) {
+ elems = Stream.concat(Stream.of("-wait"), elems);
+ }
+ return elems.collect(joining(" "));
+ }
+ }
+ }
+
+ // The sub-command: /set start <start-file>
+ 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 <start-file>
- 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<String> saveHandler = new SaveHandler(src, srcSet);
Consumer<String> 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;
}
--- 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();
}
--- 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 <mode>'' requires that <mode> is predefined or has been retained with ''/retain mode'' -- {0}
+''/set feedback -retain <mode>'' requires that <mode> 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 <file> become the default start-up snippets and commands.\n\n\
/set feedback <mode>\n\t\
Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\t\
+/set mode <mode> [<old-mode>] -command|-quiet|-delete\n\t\
Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\
/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\
Set the displayed prompts for a given feedback mode.\n\n\
/set truncation <mode> <length> <selector>...\n\t\
- Set the maximum length of a displayed value\n\
+ Set the maximum length of a displayed value.\n\n\
/set format <mode> <field> "<format>" <selector>...\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 [<command> <optional-arg>...]\n\t\
- Specify the command to launch for the /edit command.\n\t\
- The <command> is an operating system dependent string.\n\n\
-/retain start [<file>]\n\t\
- The contents of the specified <file> become the default start-up snippets and commands.\n\n\
-/retain feedback [<mode>]\n\t\
- Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/retain mode <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 = [<command>|<subject>]
help.quest =\
@@ -467,11 +457,24 @@
possible fully qualified names based on the content of the specified classpath.\n\t\t\
The "<fix-shortcut>" 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 <mode> <field> "<format>" <selector>...\n\
\n\
+Show the format settings:\n\
+\n\t\
+/set format [<mode> [<field>]]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <field> is the name of context-specific format to define.\n\
Where <format> 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 <format> shows the current format settings.\n\
+When the <mode> is specified only the format settings for that mode are shown.\n\
+When both the <mode> and <field> 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 <mode> <length> <selector>...\n\
\n\
+Show the current truncation settings:\n\
+\n\t\
+/set truncation [<mode>]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <length> is an unsigned integer representing a maximum length.\n\
Where <selector> 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 <length> shows the truncation settings.\n\
+When the <mode> 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] <mode>\n\
+\n\
+Retain the current feedback mode for future sessions:\n\
\n\t\
-/set feedback <mode>\n\
+/set feedback -retain\n\
+\n\
+Show the feedback mode and list available modes:\n\
+\n\t\
+/set feedback\n\
\n\
Where <mode> 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 <mode> 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 <mode> [<old-mode>] [-command|-quiet|-delete]\n\
+Retain a user-defined feedback mode for future sessions:\n\
+\n\t\
+/set mode -retain <mode>\n\
+\n\
+Delete a user-defined feedback mode:\n\
+\n\t\
+/set mode -delete [-retain] <mode>\n\
+\n\
+Show feedback mode settings:\n\
+\n\t\
+/set mode [<mode>]\n\
\n\
Where <new-mode> is the name of a mode you wish to create.\n\
Where <old-mode> is the name of a previously defined feedback mode.\n\
If <old-mode> 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 <mode> 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 <mode> \"<prompt>\" \"<continuation-prompt>\"\n\
\n\
+Show the normal prompt and the continuation-prompts:\n\
+\n\t\
+/set prompt [<mode>]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode.\n\
Where <prompt> and <continuation-prompt> 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 <prompt> shows the currently set prompts.\n\
+When the <mode> 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] <command>\n\
\n\t\
-/set editor [-wait] <command>|-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 <command> is an operating system dependent string.\n\
The <command> 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 <command> 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] <file>\n\
+\n\t\
+/set start [-retain] -default\n\
\n\t\
-/set start <file>|-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 <file> 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 [<mode>]\n\
-\n\
-Where <mode> is the name of a previously defined feedback mode.\n\
-You may use just enough letters to make it unique.\n\
-If the <mode> 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 <mode>\n\
+/set start -retain\n\
\n\
-Where <mode> is the name of a mode you wish to retain.\n\
-The <mode> 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 [<command>|-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 <command> 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 [<file>|-default|-none]\n\
-\n\
-If <file> is specified, the contents of the specified <file> 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 <file> 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\
--- 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<String> 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);
--- 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",
--- 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) -> {
--- 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 <mode>' requires that <mode> is predefined or has been retained with '/retain mode'"),
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode",
+ "| '/set feedback -retain <mode>' requires that <mode> 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(
--- 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<ReplTest> 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")
);
--- 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"),
--- 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: !!!!")
);
}
--- 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.")
);
}