diff --git a/util/collection/Signal.scala b/util/collection/Signal.scala index 09756249d..3152d4d49 100644 --- a/util/collection/Signal.scala +++ b/util/collection/Signal.scala @@ -2,13 +2,13 @@ package sbt object Signals { - def withHandler[T](handler: () => Unit)(action: () => T): T = + def withHandler[T](handler: () => Unit, signal: String = "INT")(action: () => T): T = { val result = try { val signals = new Signals0 - signals.withHandler(handler)(action) + signals.withHandler(signal, handler, action) } catch { case e: LinkageError => Right(action()) } @@ -26,10 +26,10 @@ private final class Signals0 { // returns a LinkageError in `action` as Left(t) in order to avoid it being // incorrectly swallowed as missing Signal/SignalHandler - def withHandler[T](handler: () => Unit)(action: () => T): Either[Throwable, T] = + def withHandler[T](signal: String, handler: () => Unit, action: () => T): Either[Throwable, T] = { import sun.misc.{Signal,SignalHandler} - val intSignal = new Signal("INT") + val intSignal = new Signal(signal) val newHandler = new SignalHandler { def handle(sig: Signal) { handler() } } diff --git a/util/complete/LineReader.scala b/util/complete/LineReader.scala index abbd0e8f5..1cb90b55b 100644 --- a/util/complete/LineReader.scala +++ b/util/complete/LineReader.scala @@ -9,6 +9,7 @@ package sbt abstract class JLine extends LineReader { + protected[this] val handleCONT: Boolean protected[this] val reader: ConsoleReader protected[this] val historyPath: Option[File] @@ -33,10 +34,22 @@ abstract class JLine extends LineReader } private[this] def readLineDirect(prompt: String, mask: Option[Char]): String = + if(handleCONT) + Signals.withHandler(() => resume(), signal = "CONT")( () => readLineDirectRaw(prompt, mask) ) + else + readLineDirectRaw(prompt, mask) + private[this] def readLineDirectRaw(prompt: String, mask: Option[Char]): String = mask match { case Some(m) => reader.readLine(prompt, m) case None => reader.readLine(prompt) } + private[this] def resume() + { + jline.Terminal.resetTerminal + JLine.terminal.disableEcho() + reader.drawLine() + reader.flushConsole() + } } private object JLine { @@ -75,15 +88,16 @@ private object JLine h.setOutput(null) } - def simple(historyPath: Option[File]): SimpleReader = new SimpleReader(historyPath) + def simple(historyPath: Option[File], handleCONT: Boolean = HandleCONT): SimpleReader = new SimpleReader(historyPath, handleCONT) val MaxHistorySize = 500 + val HandleCONT = !java.lang.Boolean.getBoolean("sbt.disable.cont") } trait LineReader { def readLine(prompt: String, mask: Option[Char] = None): Option[String] } -final class FullReader(val historyPath: Option[File], complete: Parser[_]) extends JLine +final class FullReader(val historyPath: Option[File], complete: Parser[_], val handleCONT: Boolean = JLine.HandleCONT) extends JLine { protected[this] val reader = { @@ -94,9 +108,9 @@ final class FullReader(val historyPath: Option[File], complete: Parser[_]) exten } } -class SimpleReader private[sbt] (val historyPath: Option[File]) extends JLine +class SimpleReader private[sbt] (val historyPath: Option[File], val handleCONT: Boolean) extends JLine { protected[this] val reader = JLine.createReader() } -object SimpleReader extends SimpleReader(None) +object SimpleReader extends SimpleReader(None, JLine.HandleCONT)