diff options
Diffstat (limited to 'src/compiler')
9 files changed, 91 insertions, 46 deletions
diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl index 2a42892739..0891ef8316 100644 --- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl @@ -50,6 +50,10 @@ if [ -z "$TOOL_CLASSPATH" ] ; then done fi +EXEC=exec +CYGWIN_TERM_PRE= +CYGWIN_TERM_POST= +CYGWIN_JLINE_TERMINAL= if $cygwin; then if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then format=mixed @@ -58,9 +62,19 @@ if $cygwin; then fi SCALA_HOME=`cygpath --$format "$SCALA_HOME"` TOOL_CLASSPATH=`cygpath --path --$format "$TOOL_CLASSPATH"` + case "$TERM" in + rxvt* | xterm*) + EXEC= + CYGWIN_TERM_PRE="stty -icanon min 1 -echo" + CYGWIN_TERM_POST="stty icanon echo" + CYGWIN_JLINE_TERMINAL="-Djline.terminal=jline.UnixTerminal" + trap "$CYGWIN_TERM_POST" SIGINT + ;; + esac +else + trap "stty echo" SIGINT fi -# Reminder: substitution ${JAVA_OPTS:=-Xmx256M -Xms16M} DO NOT work on Solaris [ -n "$JAVA_OPTS" ] || JAVA_OPTS="@javaflags@" # break out -D and -J options and add them to JAVA_OPTS as well @@ -97,11 +111,16 @@ if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then JAVACMD="$JAVA_HOME/bin/java" fi -exec "${JAVACMD:=java}" \ +eval $CYGWIN_TERM_PRE + +$EXEC "${JAVACMD:=java}" \ $JAVA_OPTS \ "${java_args[@@]}" \ $CPSWITCH \ -Dscala.usejavacp=true \ -Dscala.home="$SCALA_HOME" \ -Denv.emacs="$EMACS" \ + $CYGWIN_JLINE_TERMINAL \ @properties@ @class@ @toolflags@ "$@@" + +eval $CYGWIN_TERM_POST diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala index 6f2bcdb74a..ebfecc7204 100644 --- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala +++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala @@ -195,17 +195,14 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite /** Show the history */ def printHistory(xs: List[String]) { val defaultLines = 20 - - if (in.history.isEmpty) - return println("No history available.") - - val current = in.history.get.index - val count = try xs.head.toInt catch { case _: Exception => defaultLines } - val lines = in.historyList takeRight count - val offset = current - lines.size + 1 + val h = in.history getOrElse { return println("No history available.") } + val current = h.index + val count = try xs.head.toInt catch { case _: Exception => defaultLines } + val lines = in.historyList takeRight count + val offset = current - lines.size + 1 for ((line, index) <- lines.zipWithIndex) - println("%d %s".format(index + offset, line)) + println("%3d %s".format(index + offset, line.value)) } /** Some print conveniences */ @@ -216,14 +213,10 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite /** Search the history */ def searchHistory(_cmdline: String) { val cmdline = _cmdline.toLowerCase + val h = in.history getOrElse { return println("No history available.") } + val offset = h.index - h.size + 1 - if (in.history.isEmpty) - return println("No history available.") - - val current = in.history.get.index - val offset = current - in.historyList.size + 1 - - for ((line, index) <- in.historyList.zipWithIndex ; if line.toLowerCase contains cmdline) + for ((line, index) <- h.asStrings.zipWithIndex ; if line.toLowerCase contains cmdline) println("%d %s".format(index + offset, line)) } diff --git a/src/compiler/scala/tools/nsc/interpreter/Completion.scala b/src/compiler/scala/tools/nsc/interpreter/Completion.scala index 426f2debf4..971146ea14 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Completion.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Completion.scala @@ -8,6 +8,7 @@ package scala.tools.nsc package interpreter import jline._ +import jline.console.completer._ import java.util.{ List => JList } import util.returning @@ -285,8 +286,11 @@ class Completion(val repl: Interpreter) extends CompletionOutput { topLevelFor(Parsed.dotted(buf + ".", buf.length + 1)) // jline's entry point - lazy val jline: ArgumentCompletor = - returning(new ArgumentCompletor(new JLineCompletion, new JLineDelimiter))(_ setStrict false) + lazy val jline: ArgumentCompleter = { + val c = new ArgumentCompleter(new JLineDelimiter, new JLineCompletion) + c setStrict false + c + } /** This gets a little bit hairy. It's no small feat delegating everything * and also keeping track of exactly where the cursor is and where it's supposed @@ -294,7 +298,7 @@ class Completion(val repl: Interpreter) extends CompletionOutput { * string in the list of completions, that means we are expanding a unique * completion, so don't update the "last" buffer because it'll be wrong. */ - class JLineCompletion extends Completor { + class JLineCompletion extends Completer { // For recording the buffer on the last tab hit private var lastBuf: String = "" private var lastCursor: Int = -1 @@ -309,7 +313,7 @@ class Completion(val repl: Interpreter) extends CompletionOutput { else xs.reduceLeft(_ zip _ takeWhile (x => x._1 == x._2) map (_._1) mkString) // This is jline's entry point for completion. - override def complete(_buf: String, cursor: Int, candidates: JList[String]): Int = { + override def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = { val buf = if (_buf == null) "" else _buf verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0 DBG("\ncomplete(%s, %d) last = (%s, %d), verbosity: %s".format(buf, cursor, lastBuf, lastCursor, verbosity)) diff --git a/src/compiler/scala/tools/nsc/interpreter/Delimited.scala b/src/compiler/scala/tools/nsc/interpreter/Delimited.scala index cdf5a343da..a79507baa9 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Delimited.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Delimited.scala @@ -6,11 +6,11 @@ package scala.tools.nsc package interpreter -import jline.ArgumentCompletor.{ ArgumentDelimiter, ArgumentList } +import jline.console.completer.ArgumentCompleter.{ ArgumentDelimiter, ArgumentList } class JLineDelimiter extends ArgumentDelimiter { - def delimit(buffer: String, cursor: Int) = Parsed(buffer, cursor).asJlineArgumentList - def isDelimiter(buffer: String, cursor: Int) = Parsed(buffer, cursor).isDelimiter + def delimit(buffer: CharSequence, cursor: Int) = Parsed(buffer.toString, cursor).asJlineArgumentList + def isDelimiter(buffer: CharSequence, cursor: Int) = Parsed(buffer.toString, cursor).isDelimiter } trait Delimited { diff --git a/src/compiler/scala/tools/nsc/interpreter/History.scala b/src/compiler/scala/tools/nsc/interpreter/History.scala index 1dd85cda4d..4750b8ec60 100644 --- a/src/compiler/scala/tools/nsc/interpreter/History.scala +++ b/src/compiler/scala/tools/nsc/interpreter/History.scala @@ -7,18 +7,27 @@ package scala.tools.nsc package interpreter import java.io.File -import jline.{ ConsoleReader, History => JHistory } -import scala.collection.JavaConversions.asScalaBuffer +import jline.console.history._ +import jline.console.history.{ FileHistory, PersistentHistory, History => JHistory } +import jline.console.history.History.{ Entry => JEntry } +import jline.console.ConsoleReader +import scala.collection.JavaConverters._ import Properties.userHome /** Primarily, a wrapper for JLine's History. */ class History(val jhistory: JHistory) { - def asJavaList = jhistory.getHistoryList - def asList: List[String] = asScalaBuffer(asJavaList).toList - def index = jhistory.getCurrentIndex + def asJavaList = jhistory.entries() + def asStrings = asList map (_.value.toString) + def asList: List[JEntry] = asJavaList.asScala.toList + def index = jhistory.index() + def size = jhistory.size() - def grep(s: String) = asList filter (_ contains s) + def grep(s: String) = asStrings filter (_ contains s) + def flush() = jhistory match { + case x: PersistentHistory => x.flush() + case _ => () + } } object History { @@ -29,8 +38,11 @@ object History { else new History(reader.getHistory) def apply(): History = new History( - try new JHistory(new File(userHome, ScalaHistoryFile)) - // do not store history if error - catch { case _: Exception => new JHistory() } + try new FileHistory(new File(userHome, ScalaHistoryFile)) + catch { + case x: Exception => + Console.println("Error creating file history: memory history only. " + x) + new MemoryHistory() + } ) } diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala index 0d71822172..153c0b42ed 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala @@ -7,34 +7,43 @@ package scala.tools.nsc package interpreter import java.io.File -import jline.{ ConsoleReader, ArgumentCompletor, History => JHistory } +import jline.console.ConsoleReader +import jline.console.completer._ +import jline.console.history.{ History => JHistory } /** Reads from the console using JLine */ class JLineReader(interpreter: Interpreter) extends InteractiveReader { def this() = this(null) - override lazy val history = Some(History(consoleReader)) + override lazy val history = { + val h = History(consoleReader) + system addShutdownHook { + repldbg("Flushing history") + h.flush() + } + Some(h) + } override lazy val completion = Option(interpreter) map (x => new Completion(x)) - override def init() = consoleReader.getTerminal().initializeTerminal() + override def init() = consoleReader.getTerminal().init() override def redrawLine() = { - consoleReader.flushConsole() + consoleReader.flush() consoleReader.drawLine() - consoleReader.flushConsole() + consoleReader.flush() } val consoleReader = { - val r = new jline.ConsoleReader() - r setHistory (History().jhistory) + val r = new ConsoleReader() + r setHistory (History().jhistory) // placeholder r setBellEnabled false completion foreach { c => - r addCompletor c.jline - r setAutoprintThreshhold 250 + r addCompleter c.jline + r setAutoprintThreshold 250 // max completion candidates without warning } r } - override def currentLine: String = consoleReader.getCursorBuffer.getBuffer.toString + override def currentLine: String = consoleReader.getCursorBuffer.buffer.toString def readOneLine(prompt: String) = consoleReader readLine prompt val interactive = true } diff --git a/src/compiler/scala/tools/nsc/interpreter/Parsed.scala b/src/compiler/scala/tools/nsc/interpreter/Parsed.scala index d5953d3a23..c36bfd9299 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Parsed.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Parsed.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package interpreter -import jline.ArgumentCompletor.{ ArgumentDelimiter, ArgumentList } +import jline.console.completer.ArgumentCompleter.{ ArgumentDelimiter, ArgumentList } import util.returning /** One instance of a command buffer. diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala index c57874e59a..d732719d62 100644 --- a/src/compiler/scala/tools/nsc/interpreter/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/package.scala @@ -6,6 +6,13 @@ package scala.tools.nsc package object interpreter { + private[nsc] val DebugProperty = "scala.repl.debug" + private[nsc] var _debug = false + private[nsc] def isReplDebug = _debug || (system.props contains DebugProperty) + + /** Debug output */ + def repldbg(msg: String) = if (isReplDebug) Console println msg + /** Tracing */ def tracing[T](msg: String)(x: T): T = { println("(" + msg + ") " + x) ; x } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 27bdd8a391..1e03de44a0 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -137,7 +137,8 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { BooleanSetting ("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignements.") val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.") - val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") + val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") . + withPostSetHook(set => interpreter._debug = true) val Ycompletion = BooleanSetting ("-Ycompletion-debug", "Trace all tab completion activity.") val Ypmatnaive = BooleanSetting ("-Ypmat-naive", "Desugar matches as naively as possible.") val Ymurmur = BooleanSetting ("-Ymurmur", "Use Murmur hash algorithm for case class generated hashCodes.") |