sbt/util/complete/LineReader.scala

103 lines
2.6 KiB
Scala
Raw Normal View History

2010-07-28 05:01:45 +02:00
/* sbt -- Simple Build Tool
* Copyright 2008, 2009 Mark Harrah
*/
package sbt
import jline.{Completor, ConsoleReader, History}
import java.io.{File,PrintWriter}
import complete.Parser
2010-07-28 05:01:45 +02:00
abstract class JLine extends LineReader
{
protected[this] val reader: ConsoleReader
protected[this] val historyPath: Option[File]
2011-10-13 08:12:30 +02:00
def readLine(prompt: String, mask: Option[Char] = None) = JLine.withJLine { unsynchronizedReadLine(prompt, mask) }
2011-10-13 08:12:30 +02:00
private[this] def unsynchronizedReadLine(prompt: String, mask: Option[Char]) =
readLineWithHistory(prompt, mask) match
2010-07-28 05:01:45 +02:00
{
case null => None
case x => Some(x.trim)
}
private[this] def readLineWithHistory(prompt: String, mask: Option[Char]): String =
historyPath match
{
case None => readLineDirect(prompt, mask)
case Some(file) =>
val h = reader.getHistory
JLine.loadHistory(h, file)
try { readLineDirect(prompt, mask) }
finally { JLine.saveHistory(h, file) }
}
private[this] def readLineDirect(prompt: String, mask: Option[Char]): String =
mask match {
case Some(m) => reader.readLine(prompt, m)
case None => reader.readLine(prompt)
}
2010-07-28 05:01:45 +02:00
}
private object JLine
{
def terminal = jline.Terminal.getTerminal
def resetTerminal() = withTerminal { _ => jline.Terminal.resetTerminal }
private def withTerminal[T](f: jline.Terminal => T): T =
synchronized
{
val t = terminal
t.synchronized { f(t) }
}
def createReader() =
withTerminal { t =>
val cr = new ConsoleReader
t.enableEcho()
cr.setBellEnabled(false)
cr
}
def withJLine[T](action: => T): T =
withTerminal { t =>
t.disableEcho()
try { action }
finally { t.enableEcho() }
}
private[sbt] def loadHistory(h: History, file: File)
{
h.setMaxSize(MaxHistorySize)
if(file.isFile) IO.reader(file)( h.load )
}
private[sbt] def saveHistory(h: History, file: File): Unit =
Using.fileWriter()(file) { writer =>
val out = new PrintWriter(writer, false)
h.setOutput(out)
h.flushBuffer()
out.close()
h.setOutput(null)
2010-07-28 05:01:45 +02:00
}
def simple(historyPath: Option[File]): SimpleReader = new SimpleReader(historyPath)
2010-07-28 05:01:45 +02:00
val MaxHistorySize = 500
}
trait LineReader
2010-07-28 05:01:45 +02:00
{
2011-10-13 08:12:30 +02:00
def readLine(prompt: String, mask: Option[Char] = None): Option[String]
2010-07-28 05:01:45 +02:00
}
final class FullReader(val historyPath: Option[File], complete: Parser[_]) extends JLine
2010-07-28 05:01:45 +02:00
{
protected[this] val reader =
{
val cr = new ConsoleReader
cr.setBellEnabled(false)
sbt.complete.JLineCompletion.installCustomCompletor(cr, complete)
2010-07-28 05:01:45 +02:00
cr
}
}
class SimpleReader private[sbt] (val historyPath: Option[File]) extends JLine
2010-07-28 05:01:45 +02:00
{
protected[this] val reader = JLine.createReader()
2011-10-13 08:12:30 +02:00
}
object SimpleReader extends SimpleReader(None)