From 572ff48e9b2d00b85660753fc9530ee1036c47b7 Mon Sep 17 00:00:00 2001 From: extempore Date: Fri, 11 Feb 2011 04:00:46 +0000 Subject: [PATCH] This addresses a few long standing irritations with jline, rewriting chunks of it along the way. No longer does columnar output spill over and double space everything if you're unlucky with the chosen widths. Pagination works for a higher definition of work. Etc. Also, for those who enjoy operating missile systems from their repls, crash recovery now requests your permission before replaying the session. Closes #4194, no review. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@24266 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- lib/jline.jar | Bin 161805 -> 161826 bytes .../nsc/interpreter/ConsoleReaderHelper.scala | 66 ++++++++++++++++++ .../scala/tools/nsc/interpreter/ILoop.scala | 31 +++++--- .../scala/tools/nsc/interpreter/IMain.scala | 26 ++++--- .../nsc/interpreter/InteractiveReader.scala | 19 +++-- .../tools/nsc/interpreter/JLineReader.scala | 46 +++++++----- .../tools/nsc/interpreter/SimpleReader.scala | 2 + .../scala/tools/nsc/interpreter/package.scala | 18 ++++- .../nsc/interpreter/session/package.scala | 1 - src/jline/project/build.properties | 4 +- .../project/plugins/project/build.properties | 2 +- .../scala/tools/jline/WindowsTerminal.java | 2 + .../tools/jline/console/ConsoleReader.java | 10 +-- 13 files changed, 174 insertions(+), 53 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/interpreter/ConsoleReaderHelper.scala diff --git a/lib/jline.jar b/lib/jline.jar index e19911407147ecad6144911747578da0f7888f03..3ff5ffd6f8044581ccbee4f02bcd104b221df8ac 100644 GIT binary patch delta 24188 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%0A$RH~>!*np$Akg(iyYdIq5Zw!Q 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 1 + case 'q' => -1 + case _ => height - 1 + } + finally { + eraseLine() + // TODO: still not quite managing to erase --More-- and get + // back to a scala prompt without another keypress. + if (key == 'q') { + putString(getPrompt()) + redrawLine() + flush() + } + } + } + + override def printColumns(items: JCollection[_ <: CharSequence]): Unit = + printColumns(items: List[String]) + + def printColumns(items: List[String]): Unit = { + val longest = items map (_.length) max + var linesLeft = if (isPaginationEnabled()) height - 1 else Int.MaxValue + val columnSize = longest + marginSize + val padded = items map ("%-" + columnSize + "s" format _) + + padded grouped (width / columnSize) foreach { xs => + println(xs.mkString) + linesLeft -= 1 + if (linesLeft <= 0) { + linesLeft = emulateMore() + if (linesLeft < 0) + return + } + } + } +} diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 20067beda..999d760d0 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -249,13 +249,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) import global.Symbol def p(x: Any) = intp.reporter.printMessage("" + x) - def toDefString(sym: Symbol) = { - TypeStrings.quieter( - intp.afterTyper(sym.defString), - sym.owner.name + ".this.", - sym.owner.fullName + "." - ) - } // If an argument is given, only show a source with that // in its name somewhere. @@ -300,7 +293,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) p(" /* " + members.size + ownerMessage + owner.fullName + " */") memberGroups foreach { group => - group foreach (s => p(" " + toDefString(s))) + group foreach (s => p(" " + intp.symbolDefString(s))) p("") } } @@ -392,6 +385,12 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) else powerCommands ) + val replayQuestionMessage = + """|The repl compiler has crashed spectacularly. Shall I replay your + |session? I can re-run all lines except the last one. + |[y/n] + """.trim.stripMargin + private val crashRecovery: PartialFunction[Throwable, Unit] = { case ex: Throwable => if (settings.YrichExes.value) { @@ -406,9 +405,19 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) else { out.println(util.stackTraceString(ex)) } - out.println("Attempting session recovery...") - - replay() + ex match { + case _: NoSuchMethodError | _: NoClassDefFoundError => + out.println("Unrecoverable error.") + throw ex + case _ => + out.print(replayQuestionMessage) + out.flush() + if (in.readAssumingNo("")) { + out.println("\nAttempting session recovery with replay.") + replay() + } + else out.println("\nAbandoning crashed session.") + } } /** The main read-eval-print loop for the repl. It calls diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index d08c7aef3..27a6c7698 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -83,6 +83,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) { /** reporter */ lazy val reporter: ConsoleReporter = new IMain.ReplReporter(this) import reporter.{ printMessage, withoutTruncating } + // not sure if we have some motivation to print directly to console private def echo(msg: String) { Console println msg } @@ -1088,6 +1089,14 @@ class IMain(val settings: Settings, protected val out: PrintWriter) { finally isettings.unwrapStrings = saved } + def symbolDefString(sym: Symbol) = { + TypeStrings.quieter( + afterTyper(sym.defString), + sym.owner.name + ".this.", + sym.owner.fullName + "." + ) + } + def showCodeIfDebugging(code: String) { /** Secret bookcase entrance for repl debuggers: end the line * with "// show" and see what's going on. @@ -1110,6 +1119,14 @@ class IMain(val settings: Settings, protected val out: PrintWriter) { /** Utility methods for the Interpreter. */ object IMain { + // The two name forms this is catching are the two sides of this assignment: + // + // $line3.$read.$iw.$iw.Bippy = + // $line3.$read$$iw$$iw$Bippy@4a6a00ca + private def removeLineWrapper(s: String) = s.replaceAll("""\$line\d+[./]\$(read|eval|print)[$.]""", "") + private def removeIWPackages(s: String) = s.replaceAll("""\$(iw|read|eval|print)[$.]""", "") + def stripString(s: String) = removeIWPackages(removeLineWrapper(s)) + trait CodeAssembler[T] { def preamble: String def generate: T => String @@ -1152,7 +1169,7 @@ object IMain { def isTruncating = reporter.truncationOK def stripImpl(str: String): String = { - val cleaned = removeIWPackages(removeLineWrapper(str)) + val cleaned = stripString(str) var ctrlChars = 0 cleaned map { ch => if (ch.isControl && !ch.isWhitespace) { @@ -1163,13 +1180,6 @@ object IMain { else ch } } - - // The two name forms this is catching are the two sides of this assignment: - // - // $line3.$read.$iw.$iw.Bippy = - // $line3.$read$$iw$$iw$Bippy@4a6a00ca - private def removeLineWrapper(s: String) = s.replaceAll("""\$line\d+[./]\$(read|eval|print)[$.]""", "") - private def removeIWPackages(s: String) = s.replaceAll("""\$(iw|read|eval|print)[$.]""", "") } class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, null, new ReplStrippingWriter(intp)) { diff --git a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala index cef4bd893..8d9800ba0 100644 --- a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala @@ -17,17 +17,26 @@ import Properties.isMac trait InteractiveReader { val interactive: Boolean - def history: History - def completion: Completion - def keyBindings: List[KeyBinding] - def init(): Unit def reset(): Unit - protected def readOneLine(prompt: String): String + def history: History + def completion: Completion + def keyBindings: List[KeyBinding] + def eraseLine(): Unit def redrawLine(): Unit def currentLine: String + + def readYesOrNo(prompt: String) = readOneKey(prompt) match { + case 'y' => true + case 'n' => false + } + def readAssumingNo(prompt: String) = try readYesOrNo(prompt) catch { case _: MatchError => false } + def readAssumingYes(prompt: String) = try readYesOrNo(prompt) catch { case _: MatchError => true } + protected def readOneLine(prompt: String): String + protected def readOneKey(prompt: String): Int + def readLine(prompt: String): String = // hack necessary for OSX jvm suspension because read calls are not restarted after SIGTSTP if (isMac) restartSysCalls(readOneLine(prompt), reset()) diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala index bfb719f2f..a62a048cc 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala @@ -34,34 +34,42 @@ class JLineReader(val completion: Completion) extends InteractiveReader { newCursor } } - - def argCompletor: ArgumentCompleter = { - val c = new ArgumentCompleter(new JLineDelimiter, scalaToJline(completion.completer())) - c setStrict false - c - } - - val consoleReader = { - val r = new ConsoleReader() - r setBellEnabled false + + class JLineConsoleReader extends ConsoleReader with ConsoleReaderHelper { + // working around protected/trait/java insufficiencies. + def goBack(num: Int): Unit = back(num) + def readOneKey(prompt: String) = { + this.print(prompt) + this.flush() + this.readVirtualKey() + } + def eraseLine() = consoleReader.resetPromptLine("", "", 0) + def redrawLineAndFlush(): Unit = { flush() ; drawLine() ; flush() } + + this setBellEnabled false if (history ne NoHistory) - r setHistory history + this setHistory history if (completion ne NoCompletion) { - r addCompleter argCompletor - r setAutoprintThreshold 400 // max completion candidates without warning + val argCompletor: ArgumentCompleter = + new ArgumentCompleter(new JLineDelimiter, scalaToJline(completion.completer())) + argCompletor setStrict false + + this addCompleter argCompletor + this setAutoprintThreshold 400 // max completion candidates without warning } - - r } + val consoleReader: JLineConsoleReader = new JLineConsoleReader() + def currentLine: String = consoleReader.getCursorBuffer.buffer.toString - def redrawLine() = { - consoleReader.flush() - consoleReader.drawLine() - consoleReader.flush() + def redrawLine() = consoleReader.redrawLineAndFlush() + def eraseLine() = { + while (consoleReader.delete()) { } + // consoleReader.eraseLine() } def readOneLine(prompt: String) = consoleReader readLine prompt + def readOneKey(prompt: String) = consoleReader readOneKey prompt } object JLineReader { diff --git a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala index 448f5a58d..7f0d05f58 100644 --- a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala @@ -22,6 +22,7 @@ extends InteractiveReader def init() = () def reset() = () + def eraseLine() = () def redrawLine() = () def currentLine = "" def readOneLine(prompt: String): String = { @@ -31,6 +32,7 @@ extends InteractiveReader } in.readLine() } + def readOneKey(prompt: String) = sys.error("No char-based input in SimpleReader") } object SimpleReader { diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala index 298428553..1e6fcacf2 100644 --- a/src/compiler/scala/tools/nsc/interpreter/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/package.scala @@ -23,7 +23,9 @@ package scala.tools.nsc * IMain contains { global: Global } */ package object interpreter { - type JClass = java.lang.Class[_] + type JClass = java.lang.Class[_] + type JList[T] = java.util.List[T] + type JCollection[T] = java.util.Collection[T] private[nsc] val DebugProperty = "scala.repl.debug" private[nsc] val TraceProperty = "scala.repl.trace" @@ -31,6 +33,10 @@ package object interpreter { private[nsc] var isReplDebug = sys.props contains DebugProperty // Also set by -Yrepl-debug private[nsc] implicit def enrichClass[T](clazz: Class[T]) = new RichClass[T](clazz) + private[interpreter] implicit def javaCharSeqCollectionToScala(xs: JCollection[_ <: CharSequence]): List[String] = { + import collection.JavaConverters._ + xs.asScala.toList map ("" + _) + } /** Debug output */ private[nsc] def repldbg(msg: String) = if (isReplDebug) Console println msg @@ -43,6 +49,16 @@ package object interpreter { x } + // Longest common prefix + def longestCommonPrefix(xs: List[String]): String = { + if (xs.isEmpty || xs.contains("")) "" + else xs.head.head match { + case ch => + if (xs.tail forall (_.head == ch)) "" + ch + longestCommonPrefix(xs map (_.tail)) + else "" + } + } + private[nsc] def words(s: String) = s.trim split "\\s+" toList private[nsc] def isQuoted(s: String) = (s.length >= 2) && (s.head == s.last) && ("\"'" contains s.head) diff --git a/src/compiler/scala/tools/nsc/interpreter/session/package.scala b/src/compiler/scala/tools/nsc/interpreter/session/package.scala index a2ec4c2bc..50edef22e 100644 --- a/src/compiler/scala/tools/nsc/interpreter/session/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/session/package.scala @@ -12,7 +12,6 @@ package interpreter package object session { type JIterator[T] = java.util.Iterator[T] type JListIterator[T] = java.util.ListIterator[T] - type JList[T] = java.util.List[T] type JEntry = scala.tools.jline.console.history.History.Entry type JHistory = scala.tools.jline.console.history.History diff --git a/src/jline/project/build.properties b/src/jline/project/build.properties index c6143fe8d..3ecffcd80 100644 --- a/src/jline/project/build.properties +++ b/src/jline/project/build.properties @@ -3,6 +3,6 @@ project.organization=org.improving project.name=jline sbt.version=0.7.5.RC0 project.version=0.98 -#build.scala.versions=2.8.1 -build.scala.versions=2.9.0-SNAPSHOT +build.scala.versions=2.8.1 +/*build.scala.versions=2.9.0-SNAPSHOT*/ project.initialize=false diff --git a/src/jline/project/plugins/project/build.properties b/src/jline/project/plugins/project/build.properties index f39984bd7..0b7014c53 100644 --- a/src/jline/project/plugins/project/build.properties +++ b/src/jline/project/plugins/project/build.properties @@ -1,3 +1,3 @@ #Project properties -#Fri Jan 21 08:49:59 PST 2011 +#Thu Feb 10 14:58:03 PST 2011 plugin.uptodate=true diff --git a/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java b/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java index 66d2c69f8..4c70155f5 100644 --- a/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java +++ b/src/jline/src/main/java/scala/tools/jline/WindowsTerminal.java @@ -196,6 +196,8 @@ public class WindowsTerminal if (indicator == SPECIAL_KEY_INDICATOR.code || indicator == NUMPAD_KEY_INDICATOR.code) { int c = readCharacter(in); WindowsKey key = WindowsKey.valueOf(c); + if (key == null) + return 0; switch (key) { case UP_ARROW_KEY: diff --git a/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java b/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java index bff0a1064..861c2d58b 100644 --- a/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java +++ b/src/jline/src/main/java/scala/tools/jline/console/ConsoleReader.java @@ -219,7 +219,7 @@ public class ConsoleReader * * @return false if we failed (e.g., the buffer was empty) */ - final boolean resetLine() throws IOException { + protected final boolean resetLine() throws IOException { if (buf.cursor == 0) { return false; } @@ -378,7 +378,7 @@ public class ConsoleReader * @param str * @return */ - final String expandEvents(String str) throws IOException { + protected String expandEvents(String str) throws IOException { StringBuilder sb = new StringBuilder(); for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); @@ -650,7 +650,7 @@ public class ConsoleReader /** * Move the visual cursor backwards without modifying the buffer cursor. */ - private void back(final int num) throws IOException { + protected void back(final int num) throws IOException { if (num == 0) return; if (terminal.isAnsiSupported()) { int width = getTerminal().getWidth(); @@ -736,7 +736,7 @@ public class ConsoleReader return backspace(1) == 1; } - private boolean moveToEnd() throws IOException { + protected boolean moveToEnd() throws IOException { return moveCursor(buf.length() - buf.cursor) > 0; } @@ -1502,7 +1502,7 @@ public class ConsoleReader * * @return true if successful */ - private boolean complete() throws IOException { + protected boolean complete() throws IOException { // debug ("tab for (" + buf + ")"); if (completers.size() == 0) { return false;