< prev index next >
src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
Print this page
*** 24,43 ****
--- 24,48 ----
*/
package jdk.internal.jshell.tool;
import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
+ import jdk.jshell.SourceCodeAnalysis.IndexResult;
import jdk.jshell.SourceCodeAnalysis.Suggestion;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.lang.reflect.Method;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import jdk.internal.jline.NoInterruptUnixTerminal;
*** 142,151 ****
--- 147,161 ----
}
});
bind(DOCUMENTATION_SHORTCUT, (ActionListener) evt -> documentation(repl));
bind(CTRL_UP, (ActionListener) evt -> moveHistoryToSnippet(((EditingHistory) in.getHistory())::previousSnippet));
bind(CTRL_DOWN, (ActionListener) evt -> moveHistoryToSnippet(((EditingHistory) in.getHistory())::nextSnippet));
+ for (FixComputer computer : fixComputers) {
+ for (String shortcuts : SHORTCUT_FIXES) {
+ bind(shortcuts + computer.shortcut, (ActionListener) evt -> fixes(computer));
+ }
+ }
}
@Override
public String readLine(String prompt, String prefix) throws IOException, InputInterruptedException {
this.prefix = prefix;
*** 214,223 ****
--- 224,238 ----
}
private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
private static final String CTRL_UP = "\033\133\061\073\065\101"; //Ctrl-UP
private static final String CTRL_DOWN = "\033\133\061\073\065\102"; //Ctrl-DOWN
+ private static final String[] SHORTCUT_FIXES = {
+ "\033\015", //Alt-Enter (Linux)
+ "\033\133\061\067\176", //F6/Alt-F1 (Mac)
+ "\u001BO3P" //Alt-F1 (Linux)
+ };
private void documentation(JShellTool repl) {
String buffer = in.getCursorBuffer().buffer.toString();
int cursor = in.getCursorBuffer().cursor;
String doc;
*** 288,297 ****
--- 303,467 ----
@Override
public void replaceLastHistoryEntry(String source) {
history.fullHistoryReplace(source);
}
+ private void fixes(FixComputer computer) {
+ String input = prefix + in.getCursorBuffer().toString();
+ int cursor = prefix.length() + in.getCursorBuffer().cursor;
+ FixResult candidates = computer.compute(repl, input, cursor);
+
+ try {
+ final boolean printError = candidates.error != null && !candidates.error.isEmpty();
+ if (printError) {
+ in.println(candidates.error);
+ }
+ if (candidates.fixes.isEmpty()) {
+ in.beep();
+ if (printError) {
+ in.redrawLine();
+ in.flush();
+ }
+ } else if (candidates.fixes.size() == 1 && !computer.showMenu) {
+ if (printError) {
+ in.redrawLine();
+ in.flush();
+ }
+ candidates.fixes.get(0).perform(in);
+ } else {
+ List<Fix> fixes = new ArrayList<>(candidates.fixes);
+ fixes.add(0, new Fix() {
+ @Override
+ public String displayName() {
+ return "Do nothing";
+ }
+
+ @Override
+ public void perform(ConsoleReader in) throws IOException {
+ in.redrawLine();
+ }
+ });
+
+ Map<Character, Fix> char2Fix = new HashMap<>();
+ in.println();
+ for (int i = 0; i < fixes.size(); i++) {
+ Fix fix = fixes.get(i);
+ char2Fix.put((char) ('0' + i), fix);
+ in.println("" + i + ": " + fixes.get(i).displayName());
+ }
+ char2Fix.put((char) 3, fixes.get(0)); //Ctrl-C
+ in.print("Choice: ");
+ in.flush();
+ int read;
+
+ while (true) {
+ read = in.readCharacter();
+
+ Fix fix = char2Fix.get((char) read);
+
+ if (fix != null) {
+ in.println();
+
+ fix.perform(in);
+
+ in.flush();
+ break;
+ }
+ }
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public interface Fix {
+ public String displayName();
+ public void perform(ConsoleReader in) throws IOException;
+ }
+
+ public abstract static class FixComputer {
+ private final char shortcut;
+ private final boolean showMenu;
+
+ public FixComputer(char shortcut, boolean showMenu) {
+ this.shortcut = shortcut;
+ this.showMenu = showMenu;
+ }
+
+ public abstract FixResult compute(JShellTool repl, String code, int cursor);
+ }
+
+ public static class FixResult {
+ public final List<Fix> fixes;
+ public final String error;
+
+ public FixResult(List<Fix> fixes, String error) {
+ this.fixes = fixes;
+ this.error = error;
+ }
+ }
+
+ private static final FixComputer[] fixComputers = new FixComputer[] {
+ new FixComputer('v', false) {
+ @Override
+ public FixResult compute(JShellTool repl, String code, int cursor) {
+ String type = repl.analysis.analyzeType(code, cursor);
+ if (type == null) {
+ return new FixResult(Collections.emptyList(), null);
+ }
+ return new FixResult(Collections.singletonList(new Fix() {
+ @Override
+ public String displayName() {
+ return "Create variable";
+ }
+ @Override
+ public void perform(ConsoleReader in) throws IOException {
+ in.redrawLine();
+ in.setCursorPosition(0);
+ in.putString(type + " = ");
+ in.setCursorPosition(in.getCursorBuffer().cursor - 3);
+ in.flush();
+ }
+ }), null);
+ }
+ },
+ new FixComputer('i', true) {
+ @Override
+ public FixResult compute(JShellTool repl, String code, int cursor) {
+ IndexResult res = repl.analysis.getDeclaredSymbols(code, cursor);
+ List<Fix> fixes = new ArrayList<>();
+ for (String fqn : res.getFqns()) {
+ fixes.add(new Fix() {
+ @Override
+ public String displayName() {
+ return "import: " + fqn;
+ }
+ @Override
+ public void perform(ConsoleReader in) throws IOException {
+ repl.state.eval("import " + fqn + ";");
+ in.println("Imported: " + fqn);
+ in.redrawLine();
+ }
+ });
+ }
+ if (res.isResolvable()) {
+ return new FixResult(Collections.emptyList(),
+ "\nThe identifier is resolvable in this context.");
+ } else {
+ String error = "";
+ if (fixes.isEmpty()) {
+ error = "\nNo candidate FQNs found to import.";
+ }
+ if (!res.isUpToDate()) {
+ error += "\nResults may be incomplete; try again later for complete results.";
+ }
+ return new FixResult(fixes, error);
+ }
+ }
+ }
+ };
+
private static final class JShellUnixTerminal extends NoInterruptUnixTerminal {
private final StopDetectingInputStream input;
public JShellUnixTerminal(StopDetectingInputStream input) throws Exception {
< prev index next >