8178109: More useful documentation on /help
authorjlahoda
Thu, 23 Nov 2017 19:44:13 +0100
changeset 47931 b7ae1437111b
parent 47930 f2de2c55c6c7
child 47932 0c22f6b9b5e2
8178109: More useful documentation on /help Summary: For /help <command/subject>, show the help for the command/subject directly. Reviewed-by: rfield
src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties
test/langtools/jdk/jshell/ToolTabCommandTest.java
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Nov 23 18:23:15 2017 +0000
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Nov 23 19:44:13 2017 +0100
@@ -96,6 +96,7 @@
 import static java.nio.file.StandardOpenOption.CREATE;
 import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
 import static java.nio.file.StandardOpenOption.WRITE;
+import java.util.AbstractMap.SimpleEntry;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 import java.util.ServiceLoader;
@@ -1835,24 +1836,40 @@
     }
 
     public List<String> commandDocumentation(String code, int cursor, boolean shortDescription) {
-        code = code.substring(0, cursor);
-        int space = code.indexOf(' ');
-        String prefix = space != (-1) ? code.substring(0, space) : code;
+        code = code.substring(0, cursor).replaceAll("\\h+", " ");
+        String stripped = code.replaceFirst("/help ", "");
+        boolean inHelp = !code.equals(stripped);
+        int space = stripped.indexOf(' ');
+        String prefix = space != (-1) ? stripped.substring(0, space) : stripped;
         List<String> result = new ArrayList<>();
 
-        List<Entry<String, Command>> toShow =
-                commands.entrySet()
+        List<Entry<String, String>> toShow;
+
+        if (stripped.matches("/set .*") || stripped.matches("set .*")) {
+            String setSubcommand = stripped.replaceFirst("/?set ([^ ]*)($| .*)", "$1");
+            toShow =
+                Arrays.stream(SET_SUBCOMMANDS)
+                       .filter(s -> s.startsWith(setSubcommand))
+                       .map(s -> new SimpleEntry<>("/set " + s, "help.set." + s))
+                       .collect(Collectors.toList());
+        } else {
+            toShow =
+                commands.values()
                         .stream()
-                        .filter(e -> e.getKey().startsWith(prefix))
-                        .filter(e -> e.getValue().kind.showInHelp)
-                        .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
+                        .filter(c -> c.command.startsWith(prefix)
+                                     || c.command.substring(1).startsWith(prefix))
+                        .filter(c -> c.kind.showInHelp ||
+                                     (inHelp && c.kind == CommandKind.HELP_SUBJECT))
+                        .sorted((c1, c2) -> c1.command.compareTo(c2.command))
+                        .map(c -> new SimpleEntry<>(c.command, c.helpKey))
                         .collect(Collectors.toList());
-
-        if (toShow.size() == 1) {
-            result.add(getResourceString(toShow.get(0).getValue().helpKey + (shortDescription ? ".summary" : "")));
+        }
+
+        if (toShow.size() == 1 && !inHelp) {
+            result.add(getResourceString(toShow.get(0).getValue() + (shortDescription ? ".summary" : "")));
         } else {
-            for (Entry<String, Command> e : toShow) {
-                result.add(e.getKey() + "\n" +getResourceString(e.getValue().helpKey + (shortDescription ? ".summary" : "")));
+            for (Entry<String, String> e : toShow) {
+                result.add(e.getKey() + "\n" + getResourceString(e.getValue() + (shortDescription ? ".summary" : "")));
             }
         }
 
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Nov 23 18:23:15 2017 +0000
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Nov 23 19:44:13 2017 +0100
@@ -655,6 +655,9 @@
 /set mode -retain\n\n\
 See these commands for more detail -- for example /help /set editor
 
+help.set.format.summary = \
+Set the format for reporting a snippet event.
+
 help.set.format = \
 Set the format for reporting a snippet event:\n\
 \n\t\
@@ -742,6 +745,9 @@
 /set format mymode\n\
 shows the format settings for the mode mymode\n
 
+help.set.truncation.summary = \
+Set the max length of a displayed value.
+
 help.set.truncation = \
 Set the max length of a displayed value:\n\
 \n\t\
@@ -782,6 +788,9 @@
 /set truncation mymode\n\
 shows the truncation settings for the mode mymode\n
 
+help.set.feedback.summary = \
+Set the feedback mode describing displayed feedback for entered snippets and commands.
+
 help.set.feedback = \
 Set the feedback mode describing displayed feedback for entered snippets and commands:\n\
 \n\t\
@@ -804,6 +813,9 @@
 \n\
 The form without <mode> or -retain displays the current feedback mode and available modes.\n
 
+help.set.mode.summary = \
+Create a user-defined feedback mode, optionally copying from an existing mode.
+
 help.set.mode = \
 Create a user-defined feedback mode, optionally copying from an existing mode:\n\
 \n\t\
@@ -856,6 +868,9 @@
 \n\
 shows the mode, prompt, format, and truncation settings for the mode mymode
 
+help.set.prompt.summary = \
+Set the prompts.
+
 help.set.prompt = \
 Set the prompts.  Both the normal prompt and the continuation-prompt must be set:\n\
 \n\t\
@@ -877,6 +892,9 @@
 /set prompt mymode\n\
 shows the prompts set for the mode mymode\n
 
+help.set.editor.summary =\
+Specify the command to launch for the /edit command.
+
 help.set.editor =\
 Specify the command to launch for the /edit command:\n\
 \n\t\
@@ -918,6 +936,9 @@
 \n\
 The form without <command> or options shows the editor setting.\n
 
+help.set.start.summary =\
+Set the start-up configuration.
+
 help.set.start =\
 Set the start-up configuration -- a sequence of snippets and commands read at start-up:\n\
 \n\t\
--- a/test/langtools/jdk/jshell/ToolTabCommandTest.java	Thu Nov 23 18:23:15 2017 +0000
+++ b/test/langtools/jdk/jshell/ToolTabCommandTest.java	Thu Nov 23 19:44:13 2017 +0100
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8177076 8185840
+ * @bug 8177076 8185840 8178109
  * @modules
  *     jdk.compiler/com.sun.tools.javac.api
  *     jdk.compiler/com.sun.tools.javac.main
@@ -125,4 +125,67 @@
         });
     }
 
+    public void testHelp() throws Exception {
+        // set terminal height so that help output won't hit page breaks
+        System.setProperty("test.terminal.height", "1000000");
+
+        doRunTest((inputSink, out) -> {
+            inputSink.write("/help \011");
+            waitOutput(out, ".*/edit.*/list.*intro.*\n\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
+                            "\r\u0005/");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\n/edit\n" + Pattern.quote(getResource("help.edit.summary")) +
+                            "\n.*\n/list\n" + Pattern.quote(getResource("help.list.summary")) +
+                            "\n.*\nintro\n" + Pattern.quote(getResource("help.intro.summary")) +
+                            ".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/");
+            inputSink.write("/env\011");
+            waitOutput(out,   "help /env ");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\n/env\n" + Pattern.quote(getResource("help.env.summary")) +
+                            ".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/help /env ");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\n/env\n" + Pattern.quote(getResource("help.env").replaceAll("\t", "    ")) + "\n" +
+                            "\r\u0005/help /env ");
+            inputSink.write("\u0003/help intro\011");
+            waitOutput(out,   "help intro ");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\nintro\n" + Pattern.quote(getResource("help.intro.summary")) +
+                            ".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/help intro ");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\nintro\n" + Pattern.quote(getResource("help.intro").replaceAll("\t", "    ")) + "\n" +
+                            "\r\u0005/help intro ");
+            inputSink.write("\u0003/help /set \011");
+            waitOutput(out, ".*format.*truncation.*\n\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
+                            "\r\u0005/help /set ");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\n/set format\n" + Pattern.quote(getResource("help.set.format.summary")) +
+                            "\n.*\n/set truncation\n" + Pattern.quote(getResource("help.set.truncation.summary")) +
+                            ".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/help /set ");
+            inputSink.write("truncation\011");
+            waitOutput(out,   ".*truncation\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
+                            "\r\u0005/help /set truncation");
+            inputSink.write("\011");
+            waitOutput(out,   ".*/set truncation\n" + Pattern.quote(getResource("help.set.truncation.summary")) + "\n" +
+                            "\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/help /set truncation");
+            inputSink.write("\011");
+            waitOutput(out,   ".*/set truncation\n" + Pattern.quote(getResource("help.set.truncation").replaceAll("\t", "    ")) +
+                            "\r\u0005/help /set truncation");
+            inputSink.write("\u0003/help env \011");
+            waitOutput(out,   ".*\n/env\n" + Pattern.quote(getResource("help.env.summary")) +
+                            ".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/help env ");
+            inputSink.write("\u0003/help set truncation\011");
+            waitOutput(out,   ".*truncation\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
+                            "\r\u0005/help set truncation");
+            inputSink.write("\011");
+            waitOutput(out,   ".*\n/set truncation\n" + Pattern.quote(getResource("help.set.truncation.summary")) +
+                            ".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
+                            "\r\u0005/help set truncation");
+        });
+    }
 }