mirror of https://github.com/sbt/sbt.git
commit
d96ecb2c21
|
|
@ -261,6 +261,13 @@ private[sbt] object JLine3 {
|
||||||
LocalFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
LocalFlag.values.map(f => f.name.toLowerCase -> f).toMap
|
||||||
private[this] val charMap: Map[String, Attributes.ControlChar] =
|
private[this] val charMap: Map[String, Attributes.ControlChar] =
|
||||||
Attributes.ControlChar.values().map(f => f.name.toLowerCase -> f).toMap
|
Attributes.ControlChar.values().map(f => f.name.toLowerCase -> f).toMap
|
||||||
|
private[sbt] def setMode(term: Terminal, canonical: Boolean, echo: Boolean): Unit = {
|
||||||
|
val prev = attributesFromMap(term.getAttributes)
|
||||||
|
val newAttrs = new Attributes(prev)
|
||||||
|
newAttrs.setLocalFlag(LocalFlag.ICANON, canonical)
|
||||||
|
newAttrs.setLocalFlag(LocalFlag.ECHO, echo)
|
||||||
|
term.setAttributes(toMap(newAttrs))
|
||||||
|
}
|
||||||
private[util] def attributesFromMap(map: Map[String, String]): Attributes = {
|
private[util] def attributesFromMap(map: Map[String, String]): Attributes = {
|
||||||
val attributes = new Attributes
|
val attributes = new Attributes
|
||||||
map.get("iflag").foreach { flags =>
|
map.get("iflag").foreach { flags =>
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
|
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import sbt.internal.util.{ SimpleReader, Terminal }
|
import sbt.internal.util.{ SimpleReader, Terminal => ITerminal }
|
||||||
|
|
||||||
trait CommandLineUIService extends InteractionService {
|
trait CommandLineUIService extends InteractionService {
|
||||||
override def readLine(prompt: String, mask: Boolean): Option[String] = {
|
override def readLine(prompt: String, mask: Boolean): Option[String] = {
|
||||||
val maskChar = if (mask) Some('*') else None
|
val maskChar = if (mask) Some('*') else None
|
||||||
SimpleReader(Terminal.get).readLine(prompt, maskChar)
|
SimpleReader(ITerminal.get).readLine(prompt, maskChar)
|
||||||
}
|
}
|
||||||
// TODO - Implement this better.
|
// TODO - Implement this better.
|
||||||
override def confirm(msg: String): Boolean = {
|
override def confirm(msg: String): Boolean = {
|
||||||
|
|
@ -21,15 +21,15 @@ trait CommandLineUIService extends InteractionService {
|
||||||
(in == "y" || in == "yes")
|
(in == "y" || in == "yes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SimpleReader(Terminal.get).readLine(msg + " (yes/no): ", None) match {
|
SimpleReader(ITerminal.get).readLine(msg + " (yes/no): ", None) match {
|
||||||
case Some(Assent()) => true
|
case Some(Assent()) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def terminalWidth: Int = Terminal.get.getWidth
|
override def terminalWidth: Int = ITerminal.get.getWidth
|
||||||
|
|
||||||
override def terminalHeight: Int = Terminal.get.getHeight
|
override def terminalHeight: Int = ITerminal.get.getHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
object CommandLineUIService extends CommandLineUIService
|
object CommandLineUIService extends CommandLineUIService
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ import sbt.internal.server.{
|
||||||
import sbt.internal.testing.TestLogger
|
import sbt.internal.testing.TestLogger
|
||||||
import sbt.internal.util.Attributed.data
|
import sbt.internal.util.Attributed.data
|
||||||
import sbt.internal.util.Types._
|
import sbt.internal.util.Types._
|
||||||
import sbt.internal.util._
|
import sbt.internal.util.{ Terminal => ITerminal, _ }
|
||||||
import sbt.internal.util.complete._
|
import sbt.internal.util.complete._
|
||||||
import sbt.io.Path._
|
import sbt.io.Path._
|
||||||
import sbt.io._
|
import sbt.io._
|
||||||
|
|
@ -333,7 +333,7 @@ object Defaults extends BuildCommon {
|
||||||
if (!useScalaReplJLine.value) classOf[org.jline.terminal.Terminal].getClassLoader
|
if (!useScalaReplJLine.value) classOf[org.jline.terminal.Terminal].getClassLoader
|
||||||
else appConfiguration.value.provider.scalaProvider.launcher.topLoader.getParent
|
else appConfiguration.value.provider.scalaProvider.launcher.topLoader.getParent
|
||||||
},
|
},
|
||||||
useSuperShell := { if (insideCI.value) false else Terminal.console.isSupershellEnabled },
|
useSuperShell := { if (insideCI.value) false else ITerminal.console.isSupershellEnabled },
|
||||||
superShellThreshold :== SysProp.supershellThreshold,
|
superShellThreshold :== SysProp.supershellThreshold,
|
||||||
superShellMaxTasks :== SysProp.supershellMaxTasks,
|
superShellMaxTasks :== SysProp.supershellMaxTasks,
|
||||||
superShellSleep :== SysProp.supershellSleep.millis,
|
superShellSleep :== SysProp.supershellSleep.millis,
|
||||||
|
|
@ -388,6 +388,7 @@ object Defaults extends BuildCommon {
|
||||||
pollInterval :== Watch.defaultPollInterval,
|
pollInterval :== Watch.defaultPollInterval,
|
||||||
canonicalInput :== true,
|
canonicalInput :== true,
|
||||||
echoInput :== true,
|
echoInput :== true,
|
||||||
|
terminal := state.value.get(terminalKey).getOrElse(Terminal(ITerminal.get)),
|
||||||
) ++ LintUnused.lintSettings
|
) ++ LintUnused.lintSettings
|
||||||
++ DefaultBackgroundJobService.backgroundJobServiceSettings
|
++ DefaultBackgroundJobService.backgroundJobServiceSettings
|
||||||
++ RemoteCache.globalSettings
|
++ RemoteCache.globalSettings
|
||||||
|
|
@ -1663,13 +1664,13 @@ object Defaults extends BuildCommon {
|
||||||
|
|
||||||
def askForMainClass(classes: Seq[String]): Option[String] =
|
def askForMainClass(classes: Seq[String]): Option[String] =
|
||||||
sbt.SelectMainClass(
|
sbt.SelectMainClass(
|
||||||
if (classes.length >= 10) Some(SimpleReader(Terminal.get).readLine(_))
|
if (classes.length >= 10) Some(SimpleReader(ITerminal.get).readLine(_))
|
||||||
else
|
else
|
||||||
Some(s => {
|
Some(s => {
|
||||||
def print(st: String) = { scala.Console.out.print(st); scala.Console.out.flush() }
|
def print(st: String) = { scala.Console.out.print(st); scala.Console.out.flush() }
|
||||||
print(s)
|
print(s)
|
||||||
Terminal.get.withRawInput {
|
ITerminal.get.withRawInput {
|
||||||
try Terminal.get.inputStream.read match {
|
try ITerminal.get.inputStream.read match {
|
||||||
case -1 | -2 => None
|
case -1 | -2 => None
|
||||||
case b =>
|
case b =>
|
||||||
val res = b.toChar.toString
|
val res = b.toChar.toString
|
||||||
|
|
@ -1705,7 +1706,7 @@ object Defaults extends BuildCommon {
|
||||||
private[this] def termWrapper(canonical: Boolean, echo: Boolean): (() => Unit) => (() => Unit) =
|
private[this] def termWrapper(canonical: Boolean, echo: Boolean): (() => Unit) => (() => Unit) =
|
||||||
(f: () => Unit) =>
|
(f: () => Unit) =>
|
||||||
() => {
|
() => {
|
||||||
val term = Terminal.get
|
val term = ITerminal.get
|
||||||
if (!canonical) {
|
if (!canonical) {
|
||||||
term.enterRawMode()
|
term.enterRawMode()
|
||||||
if (echo) term.setEchoEnabled(echo)
|
if (echo) term.setEchoEnabled(echo)
|
||||||
|
|
@ -3952,7 +3953,7 @@ object Classpaths {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def shellPromptFromState: State => String = shellPromptFromState(Terminal.console.isColorEnabled)
|
def shellPromptFromState: State => String = shellPromptFromState(ITerminal.console.isColorEnabled)
|
||||||
def shellPromptFromState(isColorEnabled: Boolean): State => String = { s: State =>
|
def shellPromptFromState(isColorEnabled: Boolean): State => String = { s: State =>
|
||||||
val extracted = Project.extract(s)
|
val extracted = Project.extract(s)
|
||||||
(name in extracted.currentRef).get(extracted.structure.data) match {
|
(name in extracted.currentRef).get(extracted.structure.data) match {
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@ object Keys {
|
||||||
val serverLog = taskKey[Unit]("A dummy task to set server log level using Global / serverLog / logLevel.").withRank(CTask)
|
val serverLog = taskKey[Unit]("A dummy task to set server log level using Global / serverLog / logLevel.").withRank(CTask)
|
||||||
val canonicalInput = settingKey[Boolean]("Toggles whether a task should use canonical input (line buffered with echo) or raw input").withRank(DSetting)
|
val canonicalInput = settingKey[Boolean]("Toggles whether a task should use canonical input (line buffered with echo) or raw input").withRank(DSetting)
|
||||||
val echoInput = settingKey[Boolean]("Toggles whether a task should echo user input").withRank(DSetting)
|
val echoInput = settingKey[Boolean]("Toggles whether a task should echo user input").withRank(DSetting)
|
||||||
|
val terminal = taskKey[Terminal]("The Terminal associated with a task").withRank(DTask)
|
||||||
|
private[sbt] val terminalKey = AttributeKey[Terminal]("terminal-key", Invisible)
|
||||||
|
|
||||||
// Project keys
|
// Project keys
|
||||||
val autoGeneratedProject = settingKey[Boolean]("If it exists, represents that the project (and name) were automatically created, rather than user specified.").withRank(DSetting)
|
val autoGeneratedProject = settingKey[Boolean]("If it exists, represents that the project (and name) were automatically created, rather than user specified.").withRank(DSetting)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import sbt.internal.inc.ScalaInstance
|
||||||
import sbt.internal.nio.{ CheckBuildSources, FileTreeRepository }
|
import sbt.internal.nio.{ CheckBuildSources, FileTreeRepository }
|
||||||
import sbt.internal.server.{ BuildServerProtocol, NetworkChannel }
|
import sbt.internal.server.{ BuildServerProtocol, NetworkChannel }
|
||||||
import sbt.internal.util.Types.{ const, idFun }
|
import sbt.internal.util.Types.{ const, idFun }
|
||||||
import sbt.internal.util._
|
import sbt.internal.util.{ Terminal => ITerminal, _ }
|
||||||
import sbt.internal.util.complete.{ Parser, SizeParser }
|
import sbt.internal.util.complete.{ Parser, SizeParser }
|
||||||
import sbt.io._
|
import sbt.io._
|
||||||
import sbt.io.syntax._
|
import sbt.io.syntax._
|
||||||
|
|
@ -78,8 +78,8 @@ private[sbt] object xMain {
|
||||||
if (userCommands.exists(isBsp)) {
|
if (userCommands.exists(isBsp)) {
|
||||||
BspClient.run(dealiasBaseDirectory(configuration))
|
BspClient.run(dealiasBaseDirectory(configuration))
|
||||||
} else {
|
} else {
|
||||||
bootServerSocket.foreach(l => Terminal.setBootStreams(l.inputStream, l.outputStream))
|
bootServerSocket.foreach(l => ITerminal.setBootStreams(l.inputStream, l.outputStream))
|
||||||
Terminal.withStreams(true) {
|
ITerminal.withStreams(true) {
|
||||||
if (clientModByEnv || userCommands.exists(isClient)) {
|
if (clientModByEnv || userCommands.exists(isClient)) {
|
||||||
val args = userCommands.toList.filterNot(isClient)
|
val args = userCommands.toList.filterNot(isClient)
|
||||||
NetworkClient.run(dealiasBaseDirectory(configuration), args)
|
NetworkClient.run(dealiasBaseDirectory(configuration), args)
|
||||||
|
|
@ -105,7 +105,7 @@ private[sbt] object xMain {
|
||||||
} finally {
|
} finally {
|
||||||
// Clear any stray progress lines
|
// Clear any stray progress lines
|
||||||
ShutdownHooks.close()
|
ShutdownHooks.close()
|
||||||
if (Terminal.formatEnabledInEnv) {
|
if (ITerminal.formatEnabledInEnv) {
|
||||||
System.out.print(ConsoleAppender.ClearScreenAfterCursor)
|
System.out.print(ConsoleAppender.ClearScreenAfterCursor)
|
||||||
System.out.flush()
|
System.out.flush()
|
||||||
}
|
}
|
||||||
|
|
@ -118,9 +118,9 @@ private[sbt] object xMain {
|
||||||
try (Some(new BootServerSocket(configuration)) -> None)
|
try (Some(new BootServerSocket(configuration)) -> None)
|
||||||
catch {
|
catch {
|
||||||
case _: ServerAlreadyBootingException
|
case _: ServerAlreadyBootingException
|
||||||
if System.console != null && !Terminal.startedByRemoteClient =>
|
if System.console != null && !ITerminal.startedByRemoteClient =>
|
||||||
println("sbt server is already booting. Create a new server? y/n (default y)")
|
println("sbt server is already booting. Create a new server? y/n (default y)")
|
||||||
val exit = Terminal.get.withRawInput(System.in.read) match {
|
val exit = ITerminal.get.withRawInput(System.in.read) match {
|
||||||
case 110 => Some(Exit(1))
|
case 110 => Some(Exit(1))
|
||||||
case _ => None
|
case _ => None
|
||||||
}
|
}
|
||||||
|
|
@ -841,7 +841,7 @@ object BuiltinCommands {
|
||||||
@tailrec
|
@tailrec
|
||||||
private[this] def doLoadFailed(s: State, loadArg: String): State = {
|
private[this] def doLoadFailed(s: State, loadArg: String): State = {
|
||||||
s.log.warn("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)")
|
s.log.warn("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)")
|
||||||
val result = try Terminal.get.withRawInput(System.in.read) match {
|
val result = try ITerminal.get.withRawInput(System.in.read) match {
|
||||||
case -1 => 'q'.toInt
|
case -1 => 'q'.toInt
|
||||||
case b => b
|
case b => b
|
||||||
} catch { case _: ClosedChannelException => 'q' }
|
} catch { case _: ClosedChannelException => 'q' }
|
||||||
|
|
@ -957,7 +957,7 @@ object BuiltinCommands {
|
||||||
val threshold =
|
val threshold =
|
||||||
extracted.getOpt(Keys.superShellThreshold).getOrElse(SysProp.supershellThreshold)
|
extracted.getOpt(Keys.superShellThreshold).getOrElse(SysProp.supershellThreshold)
|
||||||
val maxItems = extracted.getOpt(Keys.superShellMaxTasks).getOrElse(SysProp.supershellMaxTasks)
|
val maxItems = extracted.getOpt(Keys.superShellMaxTasks).getOrElse(SysProp.supershellMaxTasks)
|
||||||
Terminal.setConsoleProgressState(new ProgressState(1, maxItems))
|
ITerminal.setConsoleProgressState(new ProgressState(1, maxItems))
|
||||||
s.put(Keys.superShellSleep.key, sleep)
|
s.put(Keys.superShellSleep.key, sleep)
|
||||||
.put(Keys.superShellThreshold.key, threshold)
|
.put(Keys.superShellThreshold.key, threshold)
|
||||||
.put(Keys.superShellMaxTasks.key, maxItems)
|
.put(Keys.superShellMaxTasks.key, maxItems)
|
||||||
|
|
@ -1032,10 +1032,10 @@ object BuiltinCommands {
|
||||||
* by a remote client and only one is able to start a server. This seems to
|
* by a remote client and only one is able to start a server. This seems to
|
||||||
* happen primarily on windows.
|
* happen primarily on windows.
|
||||||
*/
|
*/
|
||||||
if (Terminal.startedByRemoteClient && !exchange.hasServer) {
|
if (ITerminal.startedByRemoteClient && !exchange.hasServer) {
|
||||||
Exec(Shutdown, None) +: s1
|
Exec(Shutdown, None) +: s1
|
||||||
} else {
|
} else {
|
||||||
if (Terminal.console.prompt == Prompt.Batch) Terminal.console.setPrompt(Prompt.Pending)
|
if (ITerminal.console.prompt == Prompt.Batch) ITerminal.console.setPrompt(Prompt.Pending)
|
||||||
exchange prompt ConsolePromptEvent(s0)
|
exchange prompt ConsolePromptEvent(s0)
|
||||||
val minGCInterval = Project
|
val minGCInterval = Project
|
||||||
.extract(s1)
|
.extract(s1)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import sbt.internal.ShutdownHooks
|
||||||
import sbt.internal.langserver.ErrorCodes
|
import sbt.internal.langserver.ErrorCodes
|
||||||
import sbt.internal.protocol.JsonRpcResponseError
|
import sbt.internal.protocol.JsonRpcResponseError
|
||||||
import sbt.internal.nio.CheckBuildSources.CheckBuildSourcesKey
|
import sbt.internal.nio.CheckBuildSources.CheckBuildSourcesKey
|
||||||
import sbt.internal.util.{ ErrorHandling, GlobalLogBacking, Prompt, Terminal }
|
import sbt.internal.util.{ ErrorHandling, GlobalLogBacking, Prompt, Terminal => ITerminal }
|
||||||
import sbt.internal.{ ShutdownHooks, TaskProgress }
|
import sbt.internal.{ ShutdownHooks, TaskProgress }
|
||||||
import sbt.io.{ IO, Using }
|
import sbt.io.{ IO, Using }
|
||||||
import sbt.protocol._
|
import sbt.protocol._
|
||||||
|
|
@ -35,7 +35,7 @@ object MainLoop {
|
||||||
// We've disabled jline shutdown hooks to prevent classloader leaks, and have been careful to always restore
|
// We've disabled jline shutdown hooks to prevent classloader leaks, and have been careful to always restore
|
||||||
// the jline terminal in finally blocks, but hitting ctrl+c prevents finally blocks from being executed, in that
|
// the jline terminal in finally blocks, but hitting ctrl+c prevents finally blocks from being executed, in that
|
||||||
// case the only way to restore the terminal is in a shutdown hook.
|
// case the only way to restore the terminal is in a shutdown hook.
|
||||||
val shutdownHook = ShutdownHooks.add(Terminal.restore)
|
val shutdownHook = ShutdownHooks.add(ITerminal.restore)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runLoggedLoop(state, state.globalLogging.backing)
|
runLoggedLoop(state, state.globalLogging.backing)
|
||||||
|
|
@ -219,19 +219,19 @@ object MainLoop {
|
||||||
}
|
}
|
||||||
exchange.setState(progressState)
|
exchange.setState(progressState)
|
||||||
exchange.setExec(Some(exec))
|
exchange.setExec(Some(exec))
|
||||||
val restoreTerminal = channelName.flatMap(exchange.channelForName) match {
|
val (restoreTerminal, termState) = channelName.flatMap(exchange.channelForName) match {
|
||||||
case Some(c) =>
|
case Some(c) =>
|
||||||
val prevTerminal = Terminal.set(c.terminal)
|
val prevTerminal = ITerminal.set(c.terminal)
|
||||||
val prevPrompt = c.terminal.prompt
|
val prevPrompt = c.terminal.prompt
|
||||||
// temporarily set the prompt to running during task evaluation
|
// temporarily set the prompt to running during task evaluation
|
||||||
c.terminal.setPrompt(Prompt.Running)
|
c.terminal.setPrompt(Prompt.Running)
|
||||||
() => {
|
(() => {
|
||||||
c.terminal.setPrompt(prevPrompt)
|
c.terminal.setPrompt(prevPrompt)
|
||||||
Terminal.set(prevTerminal)
|
ITerminal.set(prevTerminal)
|
||||||
c.terminal.setPrompt(prevPrompt)
|
c.terminal.setPrompt(prevPrompt)
|
||||||
c.terminal.flush()
|
c.terminal.flush()
|
||||||
}
|
}) -> progressState.put(Keys.terminalKey, Terminal(c.terminal))
|
||||||
case _ => () => ()
|
case _ => (() => ()) -> progressState.put(Keys.terminalKey, Terminal(ITerminal.get))
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* FastTrackCommands.evaluate can be significantly faster than Command.process because
|
* FastTrackCommands.evaluate can be significantly faster than Command.process because
|
||||||
|
|
@ -241,8 +241,8 @@ object MainLoop {
|
||||||
*/
|
*/
|
||||||
val newState = try {
|
val newState = try {
|
||||||
FastTrackCommands
|
FastTrackCommands
|
||||||
.evaluate(progressState, exec.commandLine)
|
.evaluate(termState, exec.commandLine)
|
||||||
.getOrElse(Command.process(exec.commandLine, progressState))
|
.getOrElse(Command.process(exec.commandLine, termState))
|
||||||
} finally {
|
} finally {
|
||||||
// Flush the terminal output after command evaluation to ensure that all output
|
// Flush the terminal output after command evaluation to ensure that all output
|
||||||
// is displayed in the thin client before we report the command status. Also
|
// is displayed in the thin client before we report the command status. Also
|
||||||
|
|
@ -262,7 +262,7 @@ object MainLoop {
|
||||||
}
|
}
|
||||||
exchange.setExec(None)
|
exchange.setExec(None)
|
||||||
newState.get(sbt.Keys.currentTaskProgress).foreach(_.progress.stop())
|
newState.get(sbt.Keys.currentTaskProgress).foreach(_.progress.stop())
|
||||||
newState.remove(sbt.Keys.currentTaskProgress)
|
newState.remove(sbt.Keys.currentTaskProgress).remove(Keys.terminalKey)
|
||||||
}
|
}
|
||||||
state.get(CheckBuildSourcesKey) match {
|
state.get(CheckBuildSourcesKey) match {
|
||||||
case Some(cbs) =>
|
case Some(cbs) =>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* sbt
|
||||||
|
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||||
|
* Copyright 2008 - 2010, Mark Harrah
|
||||||
|
* Licensed under Apache License 2.0 (see LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io.{ InputStream, PrintStream }
|
||||||
|
import sbt.internal.util.{ JLine3, Terminal => ITerminal }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Terminal represents a ui connection to sbt. It may control the embedded console
|
||||||
|
* for an sbt server or it may control a remote client connected through sbtn. The
|
||||||
|
* Terminal is particularly useful whenever an sbt task needs to receive input from
|
||||||
|
* the user.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
trait Terminal {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the width of the terminal.
|
||||||
|
*
|
||||||
|
* @return the width ot the terminal
|
||||||
|
*/
|
||||||
|
def getWidth: Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the height of the terminal
|
||||||
|
*
|
||||||
|
* @return the height of the terminal
|
||||||
|
*/
|
||||||
|
def getHeight: Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An input stream associated with the terminal. Bytes inputted by the
|
||||||
|
* user may be read from this input stream.
|
||||||
|
*
|
||||||
|
* @return the terminal's input stream
|
||||||
|
*/
|
||||||
|
def inputStream: InputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A print stream associated with the terminal. Writing to this output
|
||||||
|
* stream should display text on the terminal.
|
||||||
|
*
|
||||||
|
* @return the terminal's input stream
|
||||||
|
*/
|
||||||
|
def printStream: PrintStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the mode of the terminal. By default,the terminal will be in canonical mode
|
||||||
|
* with echo enabled. This means that the terminal's inputStream will not return any
|
||||||
|
* bytes until a newline is received and that all of the characters inputed by the
|
||||||
|
* user will be echoed to the terminal's output stream.
|
||||||
|
*
|
||||||
|
* @param canonical toggles whether or not the terminal input stream is line buffered
|
||||||
|
* @param echo toggles whether or not to echo the characters received from the terminal input stream
|
||||||
|
*/
|
||||||
|
def setMode(canonical: Boolean, echo: Boolean): Unit
|
||||||
|
|
||||||
|
}
|
||||||
|
private[sbt] object Terminal {
|
||||||
|
private[sbt] def apply(term: ITerminal): Terminal = new Terminal {
|
||||||
|
override def getHeight: Int = term.getHeight
|
||||||
|
override def getWidth: Int = term.getWidth
|
||||||
|
override def inputStream: InputStream = term.inputStream
|
||||||
|
override def printStream: PrintStream = term.printStream
|
||||||
|
override def setMode(canonical: Boolean, echo: Boolean): Unit =
|
||||||
|
JLine3.setMode(term, canonical, echo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ import sbt.internal.util.{
|
||||||
GlobalLogging,
|
GlobalLogging,
|
||||||
MainAppender,
|
MainAppender,
|
||||||
Settings,
|
Settings,
|
||||||
Terminal
|
Terminal => ITerminal,
|
||||||
}
|
}
|
||||||
|
|
||||||
object PluginCommandTestPlugin0 extends AutoPlugin { override def requires = empty }
|
object PluginCommandTestPlugin0 extends AutoPlugin { override def requires = empty }
|
||||||
|
|
@ -77,7 +77,7 @@ object FakeState {
|
||||||
val logFile = File.createTempFile("sbt", ".log")
|
val logFile = File.createTempFile("sbt", ".log")
|
||||||
try {
|
try {
|
||||||
val state = FakeState(logFile, enabledPlugins: _*)
|
val state = FakeState(logFile, enabledPlugins: _*)
|
||||||
Terminal.withOut(new PrintStream(outBuffer, true)) {
|
ITerminal.withOut(new PrintStream(outBuffer, true)) {
|
||||||
MainLoop.processCommand(Exec(input, None), state)
|
MainLoop.processCommand(Exec(input, None), state)
|
||||||
}
|
}
|
||||||
new String(outBuffer.toByteArray)
|
new String(outBuffer.toByteArray)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue