Skip to content

Commit

Permalink
8158738: jshell tool: Save does not affect jshell if started from ano…
Browse files Browse the repository at this point in the history
…ther editor

Reviewed-by: jlahoda
  • Loading branch information
Robert Field committed Aug 26, 2016
1 parent 61fab7c commit 0b92f87
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Arrays;
import java.util.Scanner;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
Expand All @@ -46,17 +47,22 @@
public class ExternalEditor {
private final Consumer<String> errorHandler;
private final Consumer<String> saveHandler;
private final Consumer<String> printHandler;
private final IOContext input;
private final boolean wait;

private WatchService watcher;
private Thread watchedThread;
private Path dir;
private Path tmpfile;

ExternalEditor(Consumer<String> errorHandler, Consumer<String> saveHandler, IOContext input) {
ExternalEditor(Consumer<String> errorHandler, Consumer<String> saveHandler,
IOContext input, boolean wait, Consumer<String> printHandler) {
this.errorHandler = errorHandler;
this.saveHandler = saveHandler;
this.printHandler = printHandler;
this.input = input;
this.wait = wait;
}

private void edit(String[] cmd, String initialText) {
Expand Down Expand Up @@ -121,7 +127,16 @@ private void launch(String[] cmd) throws IOException {
try {
input.suspend();
Process process = pb.start();
process.waitFor();
// wait to exit edit mode in one of these ways...
if (wait) {
// -wait option -- ignore process exit, wait for carriage-return
Scanner scanner = new Scanner(System.in);
printHandler.accept("jshell.msg.press.return.to.leave.edit.mode");
scanner.nextLine();
} else {
// wait for process to exit
process.waitFor();
}
} catch (IOException ex) {
errorHandler.accept("process IO failure: " + ex.getMessage());
} catch (InterruptedException ex) {
Expand All @@ -148,8 +163,8 @@ private void saveFile() {
}

static void edit(String[] cmd, Consumer<String> errorHandler, String initialText,
Consumer<String> saveHandler, IOContext input) {
ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, input);
Consumer<String> saveHandler, IOContext input, boolean wait, Consumer<String> printHandler) {
ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, input, wait, printHandler);
ed.edit(cmd, initialText);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ public JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr,
private String cmdlineClasspath = null;
private String startup = null;
private String[] editor = null;
private boolean editorWait = false;

// Commands and snippets which should be replayed
private List<String> replayableHistory;
Expand Down Expand Up @@ -481,6 +482,11 @@ private void start(IOContext in, List<String> loadList) {
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);
}

Expand Down Expand Up @@ -1260,7 +1266,7 @@ final boolean cmdRetain(String arg) {
// retain editor setting
prefs.put(EDITOR_KEY, (editor == null)
? ""
: String.join(RECORD_SEPARATOR, editor));
: (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor));
return true;
case "start": {
if (!setStart(cmd, at, false)) {
Expand Down Expand Up @@ -1315,7 +1321,7 @@ String subCommand(String cmd, ArgTokenizer at, String[] subs) {

// The sub-command: /set editor <editor-command-line>>
boolean setEditor(ArgTokenizer at, boolean argsRequired) {
at.allowedOptions("-default");
at.allowedOptions("-default", "-wait");
String prog = at.next();
List<String> ed = new ArrayList<>();
while (at.val() != null) {
Expand All @@ -1326,14 +1332,20 @@ boolean setEditor(ArgTokenizer at, boolean argsRequired) {
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());
return false;
}
editor = ed.toArray(new String[ed.size()]);
editorWait = waitOption;
fluffmsg("jshell.msg.set.editor.set", prog);
} 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");
Expand Down Expand Up @@ -1720,7 +1732,8 @@ private boolean cmdEdit(String arg) {
return false;
}
} else {
ExternalEditor.edit(editor, errorHandler, src, saveHandler, input);
ExternalEditor.edit(editor, errorHandler, src, saveHandler, input,
editorWait, this::hardrb);
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument
jshell.msg.set.editor.set = Editor set to: {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.msg.try.command.without.args = Try ''{0}'' without arguments.
jshell.msg.no.active = There are no active definitions.
Expand Down Expand Up @@ -358,7 +360,7 @@ Set jshell configuration information, including:\n\
the external editor to use, the start-up definitions to use, a new feedback mode,\n\
the command prompt, the feedback mode to use, or the format of output.\n\
\n\
/set editor <command> <optional-arg>...\n\t\
/set editor [-wait] <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\
/set start <file>\n\t\
Expand Down Expand Up @@ -602,12 +604,19 @@ The continuation-prompt is used on the second and subsequent lines of a multi-li
help.set.editor =\
Specify the command to launch for the /edit command.\n\
\n\t\
/set editor <command>|-default\n\
/set editor [-wait] <command>|-default\n\
\n\
The <command> is an operating system dependent string.\n\
The <command> may include space-separated arguments (such as flags)\n\
When /edit is used, the 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.
The <command> may include space-separated arguments (such as flags)\n\n\
If the -default option is specified, the built-in default editor will be used.\n\n\
Otherwise an external editor should be specified in <command>. When <command>\n\
is used, the temporary file to edit will be appended as the last argument.\n\
Normally, edit mode will last until the external editor exits. Some external editors\n\
will exit immediately (for example, if the edit window exists) either external editor\n\
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.

help.set.start =\
Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\
Expand Down
4 changes: 3 additions & 1 deletion langtools/test/jdk/jshell/ToolCommandOptionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

/*
* @test
* @bug 8157395 8157393 8157517
* @bug 8157395 8157393 8157517 8158738
* @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolCommandOptionTest ReplToolTesting
Expand Down Expand Up @@ -148,6 +148,8 @@ public void retainEditorTest() {
"| 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",
Expand Down

0 comments on commit 0b92f87

Please sign in to comment.