646 |
654 |
647 if (cmdlineClasspath != null) { |
655 if (cmdlineClasspath != null) { |
648 state.addToClasspath(cmdlineClasspath); |
656 state.addToClasspath(cmdlineClasspath); |
649 } |
657 } |
650 |
658 |
651 String start; |
659 startUpRun(startup); |
652 if (startup == null) { |
|
653 start = startup = prefs.get(STARTUP_KEY, null); |
|
654 if (start == null) { |
|
655 start = DEFAULT_STARTUP; |
|
656 } |
|
657 } else { |
|
658 start = startup; |
|
659 } |
|
660 startUpRun(start); |
|
661 currentNameSpace = mainNamespace; |
660 currentNameSpace = mainNamespace; |
662 } |
661 } |
|
662 |
663 //where -- one-time per run initialization of feedback modes |
663 //where -- one-time per run initialization of feedback modes |
664 private void initFeedback() { |
664 private void initFeedback() { |
665 // No fluff, no prefix, for init failures |
665 // No fluff, no prefix, for init failures |
666 MessageHandler initmh = new InitMessageHandler(); |
666 MessageHandler initmh = new InitMessageHandler(); |
667 // Execute the feedback initialization code in the resource file |
667 // Execute the feedback initialization code in the resource file |
668 startUpRun(getResourceString("startup.feedback")); |
668 startUpRun(getResourceString("startup.feedback")); |
669 // These predefined modes are read-only |
669 // These predefined modes are read-only |
670 feedback.markModesReadOnly(); |
670 feedback.markModesReadOnly(); |
671 // Restore user defined modes retained on previous run with /retain mode |
671 // Restore user defined modes retained on previous run with /retain mode |
672 String encoded = prefs.get(MODE_KEY, null); |
672 String encoded = prefs.get(MODE_KEY, null); |
673 if (encoded != null) { |
673 if (encoded != null && !encoded.isEmpty()) { |
674 feedback.restoreEncodedModes(initmh, encoded); |
674 if (!feedback.restoreEncodedModes(initmh, encoded)) { |
|
675 // Catastrophic corruption -- remove the retained modes |
|
676 prefs.remove(MODE_KEY); |
|
677 } |
675 } |
678 } |
676 if (commandLineFeedbackMode != null) { |
679 if (commandLineFeedbackMode != null) { |
677 // The feedback mode to use was specified on the command line, use it |
680 // The feedback mode to use was specified on the command line, use it |
678 if (!feedback.setFeedback(initmh, new ArgTokenizer("-feedback ", commandLineFeedbackMode))) { |
681 if (!feedback.setFeedback(initmh, new ArgTokenizer("-feedback", commandLineFeedbackMode))) { |
679 regenerateOnDeath = false; |
682 regenerateOnDeath = false; |
680 } |
683 } |
681 commandLineFeedbackMode = null; |
684 commandLineFeedbackMode = null; |
682 } else { |
685 } else { |
683 String fb = prefs.get(FEEDBACK_KEY, null); |
686 String fb = prefs.get(FEEDBACK_KEY, null); |
684 if (fb != null) { |
687 if (fb != null) { |
685 // Restore the feedback mode to use that was retained |
688 // Restore the feedback mode to use that was retained |
686 // on a previous run with /retain feedback |
689 // on a previous run with /retain feedback |
687 feedback.setFeedback(initmh, new ArgTokenizer("/retain feedback ", fb)); |
690 feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb)); |
688 } |
691 } |
689 } |
692 } |
690 } |
693 } |
691 |
694 |
692 //where |
695 //where |
693 private void startUpRun(String start) { |
696 private void startUpRun(String start) { |
694 try (IOContext suin = new FileScannerIOContext(new StringReader(start))) { |
697 try (IOContext suin = new FileScannerIOContext(new StringReader(start))) { |
695 run(suin); |
698 run(suin); |
696 } catch (Exception ex) { |
699 } catch (Exception ex) { |
697 hardmsg("jshell.err.startup.unexpected.exception", ex); |
700 hardmsg("jshell.err.startup.unexpected.exception", ex); |
|
701 ex.printStackTrace(cmdout); |
698 } |
702 } |
699 } |
703 } |
700 |
704 |
701 private void closeState() { |
705 private void closeState() { |
702 live = false; |
706 live = false; |
1309 } |
1295 } |
1310 return matches[0]; |
1296 return matches[0]; |
1311 } |
1297 } |
1312 |
1298 |
1313 // The sub-command: /set editor <editor-command-line>> |
1299 // The sub-command: /set editor <editor-command-line>> |
1314 boolean setEditor(String cmd, String prog, ArgTokenizer at) { |
1300 boolean setEditor(ArgTokenizer at, boolean argsRequired) { |
|
1301 at.allowedOptions("-default"); |
|
1302 String prog = at.next(); |
1315 List<String> ed = new ArrayList<>(); |
1303 List<String> ed = new ArrayList<>(); |
1316 ed.add(prog); |
1304 while (at.val() != null) { |
1317 String n; |
1305 ed.add(at.val()); |
1318 while ((n = at.next()) != null) { |
1306 at.nextToken(); |
1319 ed.add(n); |
1307 } |
1320 } |
1308 if (!checkOptionsAndRemainingInput(at)) { |
1321 editor = ed.toArray(new String[ed.size()]); |
1309 return false; |
1322 fluffmsg("jshell.msg.set.editor.set", prog); |
1310 } |
|
1311 boolean defaultOption = at.hasOption("-default"); |
|
1312 if (prog != null) { |
|
1313 if (defaultOption) { |
|
1314 errormsg("jshell.err.default.option.or.program", at.whole()); |
|
1315 return false; |
|
1316 } |
|
1317 editor = ed.toArray(new String[ed.size()]); |
|
1318 fluffmsg("jshell.msg.set.editor.set", prog); |
|
1319 } else if (defaultOption) { |
|
1320 editor = null; |
|
1321 } else if (argsRequired) { |
|
1322 errormsg("jshell.err.set.editor.arg"); |
|
1323 return false; |
|
1324 } |
1323 return true; |
1325 return true; |
1324 } |
1326 } |
1325 |
1327 |
1326 // The sub-command: /set start <start-file> |
1328 // The sub-command: /set start <start-file> |
1327 boolean setStart(String cmd, String fn) { |
1329 boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) { |
1328 String init = readFile(fn, cmd + " start"); |
1330 at.allowedOptions("-default", "-none"); |
1329 if (init == null) { |
1331 String fn = at.next(); |
|
1332 if (!checkOptionsAndRemainingInput(at)) { |
1330 return false; |
1333 return false; |
1331 } else { |
1334 } |
1332 startup = init; |
1335 int argCount = at.optionCount() + ((fn != null) ? 1 : 0); |
1333 //prefs.put(STARTUP_KEY, init); |
1336 if (argCount > 1 || argsRequired && argCount == 0) { |
1334 return true; |
1337 errormsg("jshell.err.option.or.filename", at.whole()); |
1335 } |
1338 return false; |
|
1339 } |
|
1340 if (fn != null) { |
|
1341 String init = readFile(fn, cmd + " start"); |
|
1342 if (init == null) { |
|
1343 return false; |
|
1344 } else { |
|
1345 startup = init; |
|
1346 return true; |
|
1347 } |
|
1348 } else if (at.hasOption("-default")) { |
|
1349 startup = DEFAULT_STARTUP; |
|
1350 } else if (at.hasOption("-none")) { |
|
1351 startup = ""; |
|
1352 } |
|
1353 return true; |
1336 } |
1354 } |
1337 |
1355 |
1338 boolean cmdClasspath(String arg) { |
1356 boolean cmdClasspath(String arg) { |
1339 if (arg.isEmpty()) { |
1357 if (arg.isEmpty()) { |
1340 errormsg("jshell.err.classpath.arg"); |
1358 errormsg("jshell.err.classpath.arg"); |
1515 return sn instanceof DeclarationSnippet |
1533 return sn instanceof DeclarationSnippet |
1516 && ((DeclarationSnippet) sn).name().equals(name); |
1534 && ((DeclarationSnippet) sn).name().equals(name); |
1517 } |
1535 } |
1518 |
1536 |
1519 /** |
1537 /** |
1520 * Convert a user argument to a Stream of snippets referenced by that argument |
1538 * Convert user arguments to a Stream of snippets referenced by those |
1521 * (or lack of argument). |
1539 * arguments (or lack of arguments). |
1522 * |
|
1523 * @param snippets the base list of possible snippets |
|
1524 * @param arg the user's argument to the command, maybe be the empty string |
|
1525 * @param allowAll if true, allow the use of '-all' and '-start' |
|
1526 * @return a Stream of referenced snippets or null if no matches to specific arg |
|
1527 */ |
|
1528 private <T extends Snippet> Stream<T> argToSnippets(List<T> snippets, String arg, boolean allowAll) { |
|
1529 return argToSnippets(snippets, this::mainActive, arg, allowAll); |
|
1530 } |
|
1531 |
|
1532 /** |
|
1533 * Convert a user argument to a Stream of snippets referenced by that argument |
|
1534 * (or lack of argument). |
|
1535 * |
1540 * |
1536 * @param snippets the base list of possible snippets |
1541 * @param snippets the base list of possible snippets |
1537 * @param defFilter the filter to apply to the arguments if no argument |
1542 * @param defFilter the filter to apply to the arguments if no argument |
1538 * @param arg the user's argument to the command, maybe be the empty string |
1543 * @param rawargs the user's argument to the command, maybe be the empty |
1539 * @param allowAll if true, allow the use of '-all' and '-start' |
1544 * string |
1540 * @return a Stream of referenced snippets or null if no matches to specific arg |
1545 * @return a Stream of referenced snippets or null if no matches are found |
1541 */ |
1546 */ |
1542 private <T extends Snippet> Stream<T> argToSnippets(List<T> snippets, |
1547 private <T extends Snippet> Stream<T> argsOptionsToSnippets(List<T> snippets, |
1543 Predicate<Snippet> defFilter, String arg, boolean allowAll) { |
1548 Predicate<Snippet> defFilter, String rawargs, String cmd) { |
1544 if (allowAll && arg.equals("-all")) { |
1549 ArgTokenizer at = new ArgTokenizer(cmd, rawargs.trim()); |
|
1550 at.allowedOptions("-all", "-start"); |
|
1551 List<String> args = new ArrayList<>(); |
|
1552 String s; |
|
1553 while ((s = at.next()) != null) { |
|
1554 args.add(s); |
|
1555 } |
|
1556 if (!checkOptionsAndRemainingInput(at)) { |
|
1557 return null; |
|
1558 } |
|
1559 if (at.optionCount() > 0 && args.size() > 0) { |
|
1560 errormsg("jshell.err.may.not.specify.options.and.snippets", at.whole()); |
|
1561 return null; |
|
1562 } |
|
1563 if (at.optionCount() > 1) { |
|
1564 errormsg("jshell.err.conflicting.options", at.whole()); |
|
1565 return null; |
|
1566 } |
|
1567 if (at.hasOption("-all")) { |
1545 // all snippets including start-up, failed, and overwritten |
1568 // all snippets including start-up, failed, and overwritten |
1546 return snippets.stream(); |
1569 return snippets.stream(); |
1547 } else if (allowAll && arg.equals("-start")) { |
1570 } |
|
1571 if (at.hasOption("-start")) { |
1548 // start-up snippets |
1572 // start-up snippets |
1549 return snippets.stream() |
1573 return snippets.stream() |
1550 .filter(this::inStartUp); |
1574 .filter(this::inStartUp); |
1551 } else if (arg.isEmpty()) { |
1575 } |
|
1576 if (args.isEmpty()) { |
1552 // Default is all active user snippets |
1577 // Default is all active user snippets |
1553 return snippets.stream() |
1578 return snippets.stream() |
1554 .filter(defFilter); |
1579 .filter(defFilter); |
1555 } else { |
1580 } |
1556 Stream<T> result = |
1581 return argsToSnippets(snippets, args); |
1557 nonEmptyStream( |
1582 } |
1558 () -> snippets.stream(), |
1583 |
1559 // look for active user declarations matching the name |
1584 /** |
1560 sn -> isActive(sn) && matchingDeclaration(sn, arg), |
1585 * Convert user arguments to a Stream of snippets referenced by those |
1561 // else, look for any declarations matching the name |
1586 * arguments. |
1562 sn -> matchingDeclaration(sn, arg), |
|
1563 // else, look for an id of this name |
|
1564 sn -> sn.id().equals(arg) |
|
1565 ); |
|
1566 return result; |
|
1567 } |
|
1568 } |
|
1569 |
|
1570 /** |
|
1571 * Convert a user argument to a Stream of snippets referenced by that |
|
1572 * argument, printing an informative message if no matches. Allow '-all' and |
|
1573 * '-start'. |
|
1574 * |
1587 * |
1575 * @param snippets the base list of possible snippets |
1588 * @param snippets the base list of possible snippets |
1576 * @param defFilter the filter to apply to the arguments if no argument |
1589 * @param args the user's argument to the command, maybe be the empty list |
1577 * @param arg the user's argument to the command, maybe be the empty string |
|
1578 * @param cmd the name of the command (for use in a help message |
|
1579 * @return a Stream of referenced snippets or null if no matches to specific |
1590 * @return a Stream of referenced snippets or null if no matches to specific |
1580 * arg |
1591 * arg |
1581 */ |
1592 */ |
1582 private <T extends Snippet> Stream<T> argToSnippetsWithMessage(List<T> snippets, |
1593 private <T extends Snippet> Stream<T> argsToSnippets(List<T> snippets, |
1583 Predicate<Snippet> defFilter, String arg, String cmd) { |
1594 List<String> args) { |
1584 Stream<T> stream = argToSnippets(snippets, defFilter, arg, true); |
1595 Stream<T> result = null; |
1585 if (stream == null) { |
1596 for (String arg : args) { |
1586 errormsg("jshell.err.def.or.id.not.found", arg); |
1597 // Find the best match |
1587 // Check if there are any definitions at all |
1598 Stream<T> st = layeredSnippetSearch(snippets, arg); |
1588 if (argToSnippets(snippets, "", false).iterator().hasNext()) { |
1599 if (st == null) { |
1589 fluffmsg("jshell.msg.try.command.without.args", cmd); |
1600 Stream<Snippet> est = layeredSnippetSearch(state.snippets(), arg); |
|
1601 if (est == null) { |
|
1602 errormsg("jshell.err.no.such.snippets", arg); |
|
1603 } else { |
|
1604 errormsg("jshell.err.the.snippet.cannot.be.used.with.this.command", |
|
1605 arg, est.findFirst().get().source()); |
|
1606 } |
|
1607 return null; |
|
1608 } |
|
1609 if (result == null) { |
|
1610 result = st; |
1590 } else { |
1611 } else { |
1591 hardmsg("jshell.msg.no.active"); |
1612 result = Stream.concat(result, st); |
1592 } |
1613 } |
1593 } |
1614 } |
1594 return stream; |
1615 return result; |
1595 } |
1616 } |
1596 |
1617 |
1597 private boolean cmdDrop(String arg) { |
1618 private <T extends Snippet> Stream<T> layeredSnippetSearch(List<T> snippets, String arg) { |
1598 if (arg.isEmpty()) { |
1619 return nonEmptyStream( |
|
1620 // the stream supplier |
|
1621 () -> snippets.stream(), |
|
1622 // look for active user declarations matching the name |
|
1623 sn -> isActive(sn) && matchingDeclaration(sn, arg), |
|
1624 // else, look for any declarations matching the name |
|
1625 sn -> matchingDeclaration(sn, arg), |
|
1626 // else, look for an id of this name |
|
1627 sn -> sn.id().equals(arg) |
|
1628 ); |
|
1629 } |
|
1630 |
|
1631 private boolean cmdDrop(String rawargs) { |
|
1632 ArgTokenizer at = new ArgTokenizer("/drop", rawargs.trim()); |
|
1633 at.allowedOptions(); |
|
1634 List<String> args = new ArrayList<>(); |
|
1635 String s; |
|
1636 while ((s = at.next()) != null) { |
|
1637 args.add(s); |
|
1638 } |
|
1639 if (!checkOptionsAndRemainingInput(at)) { |
|
1640 return false; |
|
1641 } |
|
1642 if (args.isEmpty()) { |
1599 errormsg("jshell.err.drop.arg"); |
1643 errormsg("jshell.err.drop.arg"); |
1600 return false; |
1644 return false; |
1601 } |
1645 } |
1602 Stream<Snippet> stream = argToSnippets(dropableSnippets(), arg, false); |
1646 Stream<PersistentSnippet> stream = argsToSnippets(dropableSnippets(), args); |
1603 if (stream == null) { |
1647 if (stream == null) { |
1604 errormsg("jshell.err.def.or.id.not.found", arg); |
1648 // Snippet not found. Error already printed |
1605 fluffmsg("jshell.msg.see.classes.etc"); |
1649 fluffmsg("jshell.msg.see.classes.etc"); |
1606 return false; |
1650 return false; |
1607 } |
1651 } |
1608 List<Snippet> snippets = stream |
1652 List<PersistentSnippet> snippets = stream.collect(toList()); |
1609 .filter(sn -> state.status(sn).isActive && sn instanceof PersistentSnippet) |
1653 if (snippets.size() > args.size()) { |
1610 .collect(toList()); |
1654 // One of the args references more thean one snippet |
1611 if (snippets.isEmpty()) { |
|
1612 errormsg("jshell.err.drop.not.active"); |
|
1613 return false; |
|
1614 } |
|
1615 if (snippets.size() > 1) { |
|
1616 errormsg("jshell.err.drop.ambiguous"); |
1655 errormsg("jshell.err.drop.ambiguous"); |
1617 fluffmsg("jshell.msg.use.one.of", snippets.stream() |
1656 fluffmsg("jshell.msg.use.one.of", snippets.stream() |
1618 .map(sn -> String.format("\n%4s : %s", sn.id(), sn.source().replace("\n", "\n "))) |
1657 .map(sn -> String.format("\n/drop %-5s : %s", sn.id(), sn.source().replace("\n", "\n "))) |
1619 .collect(Collectors.joining(", ")) |
1658 .collect(Collectors.joining(", ")) |
1620 ); |
1659 ); |
1621 return false; |
1660 return false; |
1622 } |
1661 } |
1623 PersistentSnippet psn = (PersistentSnippet) snippets.get(0); |
1662 snippets.stream() |
1624 state.drop(psn).forEach(this::handleEvent); |
1663 .forEach(sn -> state.drop(sn).forEach(this::handleEvent)); |
1625 return true; |
1664 return true; |
1626 } |
1665 } |
1627 |
1666 |
1628 private boolean cmdEdit(String arg) { |
1667 private boolean cmdEdit(String arg) { |
1629 Stream<Snippet> stream = argToSnippetsWithMessage(state.snippets(), |
1668 Stream<Snippet> stream = argsOptionsToSnippets(state.snippets(), |
1630 this::mainActive, arg, "/edit"); |
1669 this::mainActive, arg, "/edit"); |
1631 if (stream == null) { |
1670 if (stream == null) { |
1632 return false; |
1671 return false; |
1633 } |
1672 } |
1634 Set<String> srcSet = new LinkedHashSet<>(); |
1673 Set<String> srcSet = new LinkedHashSet<>(); |
1799 live = false; |
1838 live = false; |
1800 fluffmsg("jshell.msg.resetting.state"); |
1839 fluffmsg("jshell.msg.resetting.state"); |
1801 return true; |
1840 return true; |
1802 } |
1841 } |
1803 |
1842 |
1804 private boolean cmdReload(String arg) { |
1843 private boolean cmdReload(String rawargs) { |
1805 Iterable<String> history = replayableHistory; |
1844 ArgTokenizer at = new ArgTokenizer("/reload", rawargs.trim()); |
1806 boolean echo = true; |
1845 at.allowedOptions("-restore", "-quiet"); |
1807 if (arg.length() > 0) { |
1846 if (!checkOptionsAndRemainingInput(at)) { |
1808 if ("-restore".startsWith(arg)) { |
1847 return false; |
1809 if (replayableHistoryPrevious == null) { |
1848 } |
1810 errormsg("jshell.err.reload.no.previous"); |
1849 Iterable<String> history; |
1811 return false; |
1850 if (at.hasOption("-restore")) { |
1812 } |
1851 if (replayableHistoryPrevious == null) { |
1813 history = replayableHistoryPrevious; |
1852 errormsg("jshell.err.reload.no.previous"); |
1814 } else if ("-quiet".startsWith(arg)) { |
|
1815 echo = false; |
|
1816 } else { |
|
1817 errormsg("jshell.err.arg", "/reload", arg); |
|
1818 return false; |
1853 return false; |
1819 } |
1854 } |
1820 } |
1855 history = replayableHistoryPrevious; |
1821 fluffmsg(history == replayableHistoryPrevious |
1856 fluffmsg("jshell.err.reload.restarting.previous.state"); |
1822 ? "jshell.err.reload.restarting.previous.state" |
1857 } else { |
1823 : "jshell.err.reload.restarting.state"); |
1858 history = replayableHistory; |
|
1859 fluffmsg("jshell.err.reload.restarting.state"); |
|
1860 } |
|
1861 boolean echo = !at.hasOption("-quiet"); |
1824 resetState(); |
1862 resetState(); |
1825 run(new ReloadIOContext(history, |
1863 run(new ReloadIOContext(history, |
1826 echo? cmdout : null)); |
1864 echo ? cmdout : null)); |
1827 return true; |
1865 return true; |
1828 } |
1866 } |
1829 |
1867 |
1830 private boolean cmdSave(String arg_filename) { |
1868 private boolean cmdSave(String rawargs) { |
1831 Matcher mat = HISTORY_ALL_START_FILENAME.matcher(arg_filename); |
1869 ArgTokenizer at = new ArgTokenizer("/save", rawargs.trim()); |
1832 if (!mat.find()) { |
1870 at.allowedOptions("-all", "-start", "-history"); |
1833 errormsg("jshell.err.arg", arg_filename); |
1871 String filename = at.next(); |
|
1872 if (filename == null) { |
|
1873 errormsg("jshell.err.file.filename", "/save"); |
1834 return false; |
1874 return false; |
1835 } |
1875 } |
1836 boolean useHistory = false; |
1876 if (!checkOptionsAndRemainingInput(at)) { |
1837 String saveAll = ""; |
1877 return false; |
1838 boolean saveStart = false; |
1878 } |
1839 String cmd = mat.group("cmd"); |
1879 if (at.optionCount() > 1) { |
1840 if (cmd != null) switch (cmd) { |
1880 errormsg("jshell.err.conflicting.options", at.whole()); |
1841 case "-all": |
|
1842 saveAll = "-all"; |
|
1843 break; |
|
1844 case "-history": |
|
1845 useHistory = true; |
|
1846 break; |
|
1847 case "-start": |
|
1848 saveStart = true; |
|
1849 break; |
|
1850 } |
|
1851 String filename = mat.group("filename"); |
|
1852 if (filename == null ||filename.isEmpty()) { |
|
1853 errormsg("jshell.err.file.filename", "/save"); |
|
1854 return false; |
1881 return false; |
1855 } |
1882 } |
1856 try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename), |
1883 try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename), |
1857 Charset.defaultCharset(), |
1884 Charset.defaultCharset(), |
1858 CREATE, TRUNCATE_EXISTING, WRITE)) { |
1885 CREATE, TRUNCATE_EXISTING, WRITE)) { |
1859 if (useHistory) { |
1886 if (at.hasOption("-history")) { |
1860 for (String s : input.currentSessionHistory()) { |
1887 for (String s : input.currentSessionHistory()) { |
1861 writer.write(s); |
1888 writer.write(s); |
1862 writer.write("\n"); |
1889 writer.write("\n"); |
1863 } |
1890 } |
1864 } else if (saveStart) { |
1891 } else if (at.hasOption("-start")) { |
1865 writer.append(DEFAULT_STARTUP); |
1892 writer.append(startup); |
1866 } else { |
1893 } else { |
1867 Stream<Snippet> stream = argToSnippets(state.snippets(), saveAll, true); |
1894 List<Snippet> sns = at.hasOption("-all") |
1868 if (stream != null) { |
1895 ? state.snippets() |
1869 for (Snippet sn : stream.collect(toList())) { |
1896 : state.snippets().stream().filter(this::mainActive).collect(toList()); |
1870 writer.write(sn.source()); |
1897 for (Snippet sn : sns) { |
1871 writer.write("\n"); |
1898 writer.write(sn.source()); |
1872 } |
1899 writer.write("\n"); |
1873 } |
1900 } |
1874 } |
1901 } |
1875 } catch (FileNotFoundException e) { |
1902 } catch (FileNotFoundException e) { |
1876 errormsg("jshell.err.file.not.found", "/save", filename, e.getMessage()); |
1903 errormsg("jshell.err.file.not.found", "/save", filename, e.getMessage()); |
1877 return false; |
1904 return false; |