From 9353bf9d203c0361ce9c95b08efbff70df881b8b Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 9 Mar 2018 14:23:09 +0200 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87=D0=B8?= =?UTF-8?q?=D0=BA=20=D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B2=D0=B2=D0=BE=D0=B4=D0=B0=20JLine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../java/com/annimon/ownlang/utils/Repl.java | 24 +++++++---- .../ownlang/utils/repl/JLineConsole.java | 41 +++++++++++++++++++ .../ownlang/utils/repl/ReplConsole.java | 10 +++++ .../ownlang/utils/repl/SystemConsole.java | 31 ++++++++++++++ 5 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/annimon/ownlang/utils/repl/JLineConsole.java create mode 100644 src/main/java/com/annimon/ownlang/utils/repl/ReplConsole.java create mode 100644 src/main/java/com/annimon/ownlang/utils/repl/SystemConsole.java diff --git a/build.gradle b/build.gradle index 0fed546..5e72a55 100644 --- a/build.gradle +++ b/build.gradle @@ -93,6 +93,7 @@ dependencies { } compile 'org.json:json:20160212' compile 'org.yaml:snakeyaml:1.17' + compile 'jline:jline:2.14.5' testCompile 'junit:junit:4.12' testCompile 'org.openjdk.jmh:jmh-core:1.13' diff --git a/src/main/java/com/annimon/ownlang/utils/Repl.java b/src/main/java/com/annimon/ownlang/utils/Repl.java index bef51f4..43d3986 100644 --- a/src/main/java/com/annimon/ownlang/utils/Repl.java +++ b/src/main/java/com/annimon/ownlang/utils/Repl.java @@ -13,11 +13,14 @@ import com.annimon.ownlang.parser.Token; import com.annimon.ownlang.parser.ast.BlockStatement; import com.annimon.ownlang.parser.ast.Statement; import com.annimon.ownlang.parser.visitors.PrintVisitor; +import com.annimon.ownlang.utils.repl.JLineConsole; +import com.annimon.ownlang.utils.repl.ReplConsole; +import com.annimon.ownlang.utils.repl.SystemConsole; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Scanner; import java.util.stream.Collectors; public final class Repl { @@ -36,14 +39,13 @@ public final class Repl { final BlockStatement history = new BlockStatement(); final StringBuilder buffer = new StringBuilder(); - final Scanner scanner = new Scanner(System.in); + final ReplConsole console = initReplConsole(); while (true) { - System.out.print((buffer.length() == 0) ? "\n> " : " "); + console.setPrompt((buffer.length() == 0) ? "\n> " : " "); - if (!scanner.hasNextLine()) break; + final String line = console.readLine(); + if (line == null || EXIT.equalsIgnoreCase(line)) break; - final String line = scanner.nextLine(); - if (EXIT.equalsIgnoreCase(line)) break; switch (line.toLowerCase(Locale.ENGLISH)) { case RESET: buffer.setLength(0); @@ -84,7 +86,15 @@ public final class Repl { } buffer.setLength(0); } - scanner.close(); + console.close(); + } + + private static ReplConsole initReplConsole() { + try { + return new JLineConsole(); + } catch (IOException ioe) { + return new SystemConsole(); + } } private static void printHelp(boolean full) { diff --git a/src/main/java/com/annimon/ownlang/utils/repl/JLineConsole.java b/src/main/java/com/annimon/ownlang/utils/repl/JLineConsole.java new file mode 100644 index 0000000..04b0611 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/utils/repl/JLineConsole.java @@ -0,0 +1,41 @@ +package com.annimon.ownlang.utils.repl; + +import java.io.IOException; +import jline.TerminalFactory; +import jline.console.ConsoleReader; + +public class JLineConsole implements ReplConsole { + + private final ConsoleReader console; + + public JLineConsole() throws IOException { + console = new ConsoleReader(); + } + + public ConsoleReader getConsole() { + return console; + } + + @Override + public void setPrompt(String prompt) { + console.setPrompt(prompt); + } + + @Override + public String readLine() { + try { + return console.readLine(); + } catch (IOException ex) { + return null; + } + } + + @Override + public void close() { + try { + TerminalFactory.get().restore(); + } catch (Exception ignored) { + } + } + +} diff --git a/src/main/java/com/annimon/ownlang/utils/repl/ReplConsole.java b/src/main/java/com/annimon/ownlang/utils/repl/ReplConsole.java new file mode 100644 index 0000000..ac65bae --- /dev/null +++ b/src/main/java/com/annimon/ownlang/utils/repl/ReplConsole.java @@ -0,0 +1,10 @@ +package com.annimon.ownlang.utils.repl; + +public interface ReplConsole { + + void setPrompt(String prompt); + + String readLine(); + + void close(); +} diff --git a/src/main/java/com/annimon/ownlang/utils/repl/SystemConsole.java b/src/main/java/com/annimon/ownlang/utils/repl/SystemConsole.java new file mode 100644 index 0000000..6816fe6 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/utils/repl/SystemConsole.java @@ -0,0 +1,31 @@ +package com.annimon.ownlang.utils.repl; + +import java.util.Scanner; + +public class SystemConsole implements ReplConsole { + + private final Scanner scanner; + + public SystemConsole() { + scanner = new Scanner(System.in); + } + + @Override + public void setPrompt(String prompt) { + System.out.print(prompt); + } + + @Override + public String readLine() { + if (!scanner.hasNextLine()) { + return null; + } + return scanner.nextLine(); + } + + @Override + public void close() { + scanner.close(); + } + +}