langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
changeset 42827 36468b5fa7f4
parent 42415 85388bae723d
child 42843 a8d83044a192
equal deleted inserted replaced
42826:563b42fc70ba 42827:36468b5fa7f4
   450     }
   450     }
   451 
   451 
   452     <T> void hardPairs(Stream<T> stream, Function<T, String> a, Function<T, String> b) {
   452     <T> void hardPairs(Stream<T> stream, Function<T, String> a, Function<T, String> b) {
   453         Map<String, String> a2b = stream.collect(toMap(a, b,
   453         Map<String, String> a2b = stream.collect(toMap(a, b,
   454                 (m1, m2) -> m1,
   454                 (m1, m2) -> m1,
   455                 () -> new LinkedHashMap<>()));
   455                 LinkedHashMap::new));
   456         for (Entry<String, String> e : a2b.entrySet()) {
   456         for (Entry<String, String> e : a2b.entrySet()) {
   457             hard("%s", e.getKey());
   457             hard("%s", e.getKey());
   458             rawout(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
   458             rawout(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
   459         }
   459         }
   460     }
   460     }
   951 
   951 
   952         return commands.values()
   952         return commands.values()
   953                        .stream()
   953                        .stream()
   954                        .filter(filter)
   954                        .filter(filter)
   955                        .filter(command -> command.command.startsWith(cmd))
   955                        .filter(command -> command.command.startsWith(cmd))
   956                        .toArray(size -> new Command[size]);
   956                        .toArray(Command[]::new);
   957     }
   957     }
   958 
   958 
   959     private static Path toPathResolvingUserHome(String pathString) {
   959     private static Path toPathResolvingUserHome(String pathString) {
   960         if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
   960         if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
   961             return Paths.get(System.getProperty("user.home"), pathString.substring(2));
   961             return Paths.get(System.getProperty("user.home"), pathString.substring(2));
  1123                                      || !prior.contains(((DeclarationSnippet) k).name())))
  1123                                      || !prior.contains(((DeclarationSnippet) k).name())))
  1124                         .flatMap(k -> (k instanceof DeclarationSnippet)
  1124                         .flatMap(k -> (k instanceof DeclarationSnippet)
  1125                                 ? Stream.of(String.valueOf(k.id()) + " ", ((DeclarationSnippet) k).name() + " ")
  1125                                 ? Stream.of(String.valueOf(k.id()) + " ", ((DeclarationSnippet) k).name() + " ")
  1126                                 : Stream.of(String.valueOf(k.id()) + " "))
  1126                                 : Stream.of(String.valueOf(k.id()) + " "))
  1127                         .filter(k -> k.startsWith(argPrefix))
  1127                         .filter(k -> k.startsWith(argPrefix))
  1128                         .map(k -> new ArgSuggestion(k))
  1128                         .map(ArgSuggestion::new)
  1129                         .collect(Collectors.toList());
  1129                         .collect(Collectors.toList());
  1130         };
  1130         };
  1131     }
  1131     }
  1132 
  1132 
  1133     // Completion based on snippet supplier with -all -start (and sometimes -history) options
  1133     // Completion based on snippet supplier with -all -start (and sometimes -history) options
  1152             int pastSpace = code.indexOf(' ') + 1; // zero if no space
  1152             int pastSpace = code.indexOf(' ') + 1; // zero if no space
  1153             if (pastSpace == 0) {
  1153             if (pastSpace == 0) {
  1154                 result = new FixedCompletionProvider(commands.values().stream()
  1154                 result = new FixedCompletionProvider(commands.values().stream()
  1155                         .filter(cmd -> cmd.kind.showInHelp || cmd.kind == CommandKind.HELP_SUBJECT)
  1155                         .filter(cmd -> cmd.kind.showInHelp || cmd.kind == CommandKind.HELP_SUBJECT)
  1156                         .map(c -> c.command + " ")
  1156                         .map(c -> c.command + " ")
  1157                         .toArray(size -> new String[size]))
  1157                         .toArray(String[]::new))
  1158                         .completionSuggestions(code, cursor, anchor);
  1158                         .completionSuggestions(code, cursor, anchor);
  1159             } else if (code.startsWith("/se")) {
  1159             } else if (code.startsWith("/se")) {
  1160                 result = new FixedCompletionProvider(SET_SUBCOMMANDS)
  1160                 result = new FixedCompletionProvider(SET_SUBCOMMANDS)
  1161                         .completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor);
  1161                         .completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor);
  1162             } else {
  1162             } else {
  1262 
  1262 
  1263     // Table of commands -- with command forms, argument kinds, helpKey message, implementation, ...
  1263     // Table of commands -- with command forms, argument kinds, helpKey message, implementation, ...
  1264 
  1264 
  1265     {
  1265     {
  1266         registerCommand(new Command("/list",
  1266         registerCommand(new Command("/list",
  1267                 arg -> cmdList(arg),
  1267                 this::cmdList,
  1268                 snippetWithOptionCompletion(SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER,
  1268                 snippetWithOptionCompletion(SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER,
  1269                         this::allSnippets)));
  1269                         this::allSnippets)));
  1270         registerCommand(new Command("/edit",
  1270         registerCommand(new Command("/edit",
  1271                 arg -> cmdEdit(arg),
  1271                 this::cmdEdit,
  1272                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1272                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1273                         this::allSnippets)));
  1273                         this::allSnippets)));
  1274         registerCommand(new Command("/drop",
  1274         registerCommand(new Command("/drop",
  1275                 arg -> cmdDrop(arg),
  1275                 this::cmdDrop,
  1276                 snippetCompletion(this::dropableSnippets),
  1276                 snippetCompletion(this::dropableSnippets),
  1277                 CommandKind.REPLAY));
  1277                 CommandKind.REPLAY));
  1278         registerCommand(new Command("/save",
  1278         registerCommand(new Command("/save",
  1279                 arg -> cmdSave(arg),
  1279                 this::cmdSave,
  1280                 saveCompletion()));
  1280                 saveCompletion()));
  1281         registerCommand(new Command("/open",
  1281         registerCommand(new Command("/open",
  1282                 arg -> cmdOpen(arg),
  1282                 this::cmdOpen,
  1283                 FILE_COMPLETION_PROVIDER));
  1283                 FILE_COMPLETION_PROVIDER));
  1284         registerCommand(new Command("/vars",
  1284         registerCommand(new Command("/vars",
  1285                 arg -> cmdVars(arg),
  1285                 this::cmdVars,
  1286                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1286                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1287                         this::allVarSnippets)));
  1287                         this::allVarSnippets)));
  1288         registerCommand(new Command("/methods",
  1288         registerCommand(new Command("/methods",
  1289                 arg -> cmdMethods(arg),
  1289                 this::cmdMethods,
  1290                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1290                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1291                         this::allMethodSnippets)));
  1291                         this::allMethodSnippets)));
  1292         registerCommand(new Command("/types",
  1292         registerCommand(new Command("/types",
  1293                 arg -> cmdTypes(arg),
  1293                 this::cmdTypes,
  1294                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1294                 snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
  1295                         this::allTypeSnippets)));
  1295                         this::allTypeSnippets)));
  1296         registerCommand(new Command("/imports",
  1296         registerCommand(new Command("/imports",
  1297                 arg -> cmdImports(),
  1297                 arg -> cmdImports(),
  1298                 EMPTY_COMPLETION_PROVIDER));
  1298                 EMPTY_COMPLETION_PROVIDER));
  1301                 EMPTY_COMPLETION_PROVIDER));
  1301                 EMPTY_COMPLETION_PROVIDER));
  1302         registerCommand(new Command("/reset",
  1302         registerCommand(new Command("/reset",
  1303                 arg -> cmdReset(),
  1303                 arg -> cmdReset(),
  1304                 EMPTY_COMPLETION_PROVIDER));
  1304                 EMPTY_COMPLETION_PROVIDER));
  1305         registerCommand(new Command("/reload",
  1305         registerCommand(new Command("/reload",
  1306                 arg -> cmdReload(arg),
  1306                 this::cmdReload,
  1307                 reloadCompletion()));
  1307                 reloadCompletion()));
  1308         registerCommand(new Command("/classpath",
  1308         registerCommand(new Command("/classpath",
  1309                 arg -> cmdClasspath(arg),
  1309                 this::cmdClasspath,
  1310                 classPathCompletion(),
  1310                 classPathCompletion(),
  1311                 CommandKind.REPLAY));
  1311                 CommandKind.REPLAY));
  1312         registerCommand(new Command("/history",
  1312         registerCommand(new Command("/history",
  1313                 arg -> cmdHistory(),
  1313                 arg -> cmdHistory(),
  1314                 EMPTY_COMPLETION_PROVIDER));
  1314                 EMPTY_COMPLETION_PROVIDER));
  1315         registerCommand(new Command("/debug",
  1315         registerCommand(new Command("/debug",
  1316                 arg -> cmdDebug(arg),
  1316                 this::cmdDebug,
  1317                 EMPTY_COMPLETION_PROVIDER,
  1317                 EMPTY_COMPLETION_PROVIDER,
  1318                 CommandKind.HIDDEN));
  1318                 CommandKind.HIDDEN));
  1319         registerCommand(new Command("/help",
  1319         registerCommand(new Command("/help",
  1320                 arg -> cmdHelp(arg),
  1320                 this::cmdHelp,
  1321                 helpCompletion()));
  1321                 helpCompletion()));
  1322         registerCommand(new Command("/set",
  1322         registerCommand(new Command("/set",
  1323                 arg -> cmdSet(arg),
  1323                 this::cmdSet,
  1324                 new ContinuousCompletionProvider(Map.of(
  1324                 new ContinuousCompletionProvider(Map.of(
  1325                         // need more completion for format for usability
  1325                         // need more completion for format for usability
  1326                         "format", feedback.modeCompletions(),
  1326                         "format", feedback.modeCompletions(),
  1327                         "truncation", feedback.modeCompletions(),
  1327                         "truncation", feedback.modeCompletions(),
  1328                         "feedback", feedback.modeCompletions(),
  1328                         "feedback", feedback.modeCompletions(),
  1333                         "editor", fileCompletions(Files::isExecutable),
  1333                         "editor", fileCompletions(Files::isExecutable),
  1334                         "start", FILE_COMPLETION_PROVIDER),
  1334                         "start", FILE_COMPLETION_PROVIDER),
  1335                         STARTSWITH_MATCHER)));
  1335                         STARTSWITH_MATCHER)));
  1336         registerCommand(new Command("/?",
  1336         registerCommand(new Command("/?",
  1337                 "help.quest",
  1337                 "help.quest",
  1338                 arg -> cmdHelp(arg),
  1338                 this::cmdHelp,
  1339                 helpCompletion(),
  1339                 helpCompletion(),
  1340                 CommandKind.NORMAL));
  1340                 CommandKind.NORMAL));
  1341         registerCommand(new Command("/!",
  1341         registerCommand(new Command("/!",
  1342                 "help.bang",
  1342                 "help.bang",
  1343                 arg -> cmdUseHistoryEntry(-1),
  1343                 arg -> cmdUseHistoryEntry(-1),
  1448                     ? "_retain"
  1448                     ? "_retain"
  1449                     : "_blank";
  1449                     : "_blank";
  1450         }
  1450         }
  1451         String[] matches = Arrays.stream(subs)
  1451         String[] matches = Arrays.stream(subs)
  1452                 .filter(s -> s.startsWith(sub))
  1452                 .filter(s -> s.startsWith(sub))
  1453                 .toArray(size -> new String[size]);
  1453                 .toArray(String[]::new);
  1454         if (matches.length == 0) {
  1454         if (matches.length == 0) {
  1455             // There are no matching sub-commands
  1455             // There are no matching sub-commands
  1456             errormsg("jshell.err.arg", cmd, sub);
  1456             errormsg("jshell.err.arg", cmd, sub);
  1457             fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs)
  1457             fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs)
  1458                     .collect(Collectors.joining(", "))
  1458                     .collect(Collectors.joining(", "))
  1782         ArgTokenizer at = new ArgTokenizer("/help", arg);
  1782         ArgTokenizer at = new ArgTokenizer("/help", arg);
  1783         String subject = at.next();
  1783         String subject = at.next();
  1784         if (subject != null) {
  1784         if (subject != null) {
  1785             Command[] matches = commands.values().stream()
  1785             Command[] matches = commands.values().stream()
  1786                     .filter(c -> c.command.startsWith(subject))
  1786                     .filter(c -> c.command.startsWith(subject))
  1787                     .toArray(size -> new Command[size]);
  1787                     .toArray(Command[]::new);
  1788             if (matches.length == 1) {
  1788             if (matches.length == 1) {
  1789                 String cmd = matches[0].command;
  1789                 String cmd = matches[0].command;
  1790                 if (cmd.equals("/set")) {
  1790                 if (cmd.equals("/set")) {
  1791                     // Print the help doc for the specified sub-command
  1791                     // Print the help doc for the specified sub-command
  1792                     String which = subCommand(cmd, at, SET_SUBCOMMANDS);
  1792                     String which = subCommand(cmd, at, SET_SUBCOMMANDS);
  2412      * @param diagnostics input list
  2412      * @param diagnostics input list
  2413      * @return filtered list
  2413      * @return filtered list
  2414      */
  2414      */
  2415     List<Diag> errorsOnly(List<Diag> diagnostics) {
  2415     List<Diag> errorsOnly(List<Diag> diagnostics) {
  2416         return diagnostics.stream()
  2416         return diagnostics.stream()
  2417                 .filter(d -> d.isError())
  2417                 .filter(Diag::isError)
  2418                 .collect(toList());
  2418                 .collect(toList());
  2419     }
  2419     }
  2420 
  2420 
  2421     void displayDiagnostics(String source, Diag diag, List<String> toDisplay) {
  2421     void displayDiagnostics(String source, Diag diag, List<String> toDisplay) {
  2422         for (String line : diag.getMessage(null).split("\\r?\\n")) { // TODO: Internationalize
  2422         for (String line : diag.getMessage(null).split("\\r?\\n")) { // TODO: Internationalize