handle CONT signal to reset JLine after resuming from stop. fixes #394

This commit is contained in:
Mark Harrah 2012-03-09 07:08:38 -05:00
parent 3587777638
commit 5b20d330c5
2 changed files with 22 additions and 8 deletions

View File

@ -2,13 +2,13 @@ package sbt
object Signals object Signals
{ {
def withHandler[T](handler: () => Unit)(action: () => T): T = def withHandler[T](handler: () => Unit, signal: String = "INT")(action: () => T): T =
{ {
val result = val result =
try try
{ {
val signals = new Signals0 val signals = new Signals0
signals.withHandler(handler)(action) signals.withHandler(signal, handler, action)
} }
catch { case e: LinkageError => Right(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 // returns a LinkageError in `action` as Left(t) in order to avoid it being
// incorrectly swallowed as missing Signal/SignalHandler // 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} import sun.misc.{Signal,SignalHandler}
val intSignal = new Signal("INT") val intSignal = new Signal(signal)
val newHandler = new SignalHandler { val newHandler = new SignalHandler {
def handle(sig: Signal) { handler() } def handle(sig: Signal) { handler() }
} }

View File

@ -9,6 +9,7 @@ package sbt
abstract class JLine extends LineReader abstract class JLine extends LineReader
{ {
protected[this] val handleCONT: Boolean
protected[this] val reader: ConsoleReader protected[this] val reader: ConsoleReader
protected[this] val historyPath: Option[File] 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 = 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 { mask match {
case Some(m) => reader.readLine(prompt, m) case Some(m) => reader.readLine(prompt, m)
case None => reader.readLine(prompt) case None => reader.readLine(prompt)
} }
private[this] def resume()
{
jline.Terminal.resetTerminal
JLine.terminal.disableEcho()
reader.drawLine()
reader.flushConsole()
}
} }
private object JLine private object JLine
{ {
@ -75,15 +88,16 @@ private object JLine
h.setOutput(null) 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 MaxHistorySize = 500
val HandleCONT = !java.lang.Boolean.getBoolean("sbt.disable.cont")
} }
trait LineReader trait LineReader
{ {
def readLine(prompt: String, mask: Option[Char] = None): Option[String] 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 = 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() protected[this] val reader = JLine.createReader()
} }
object SimpleReader extends SimpleReader(None) object SimpleReader extends SimpleReader(None, JLine.HandleCONT)