8131023: JShell: System.in does not work
authorjlahoda
Thu, 01 Sep 2016 10:30:13 +0200
changeset 40698 a6fd340cc851
parent 40697 9621fb9e629c
child 40699 df9fab06ba9d
8131023: JShell: System.in does not work Summary: Read prompt lentgh directly from the terminal Reviewed-by: rfield
jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/ConsoleReader.java
--- a/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/ConsoleReader.java	Wed Aug 31 16:16:01 2016 -0700
+++ b/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/console/ConsoleReader.java	Thu Sep 01 10:30:13 2016 +0200
@@ -39,6 +39,7 @@
 //import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.Stack;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import jdk.internal.jline.Terminal;
@@ -2336,6 +2337,33 @@
                 out.flush();
             }
 
+            Stack<Character> pushBackChar = new Stack<Character>();
+
+            if (terminal.isAnsiSupported()) {
+                //detect the prompt length by reading the cursor position from the terminal
+                //the real prompt length could differ from the simple prompt length due to
+                //use of escape sequences:
+                out.write("\033[6n");
+                out.flush();
+                StringBuilder input = new StringBuilder();
+                while (true) {
+                    int read;
+                    while ((read = in.read()) != 'R') {
+                        input.appendCodePoint(read);
+                    }
+                    input.appendCodePoint(read);
+                    Matcher m = CURSOR_COLUMN_PATTERN.matcher(input);
+                    if (m.matches()) {
+                        promptLen = Integer.parseInt(m.group("column")) - 1;
+                        String prefix = m.group("prefix");
+                        for (int i = prefix.length() - 1; i >= 0; i--) {
+                            pushBackChar.push(prefix.charAt(i));
+                        }
+                        break;
+                    }
+                }
+            }
+
             // if the terminal is unsupported, just use plain-java reading
             if (!terminal.isSupported()) {
                 return readLineSimple();
@@ -2352,7 +2380,6 @@
             boolean success = true;
 
             StringBuilder sb = new StringBuilder();
-            Stack<Character> pushBackChar = new Stack<Character>();
             while (true) {
                 int c = pushBackChar.isEmpty() ? readCharacter() : pushBackChar.pop ();
                 if (c == -1) {
@@ -3193,6 +3220,9 @@
             }
         }
     }
+    //where:
+        private Pattern CURSOR_COLUMN_PATTERN =
+                Pattern.compile("(?<prefix>.*)\033\\[[0-9]+;(?<column>[0-9]+)R");
 
     /**
      * Read a line for unsupported terminals.