Merge pull request #4418 from eatkins/interactive

Interactive
This commit is contained in:
Ethan Atkins 2018-10-10 20:01:58 -07:00 committed by GitHub
commit c9a0698a18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 20 deletions

View File

@ -109,27 +109,34 @@ object Watched {
type WatchSource = Source
def terminateWatch(key: Int): Boolean = Watched.isEnter(key)
private def withCharBufferedStdIn[R](f: InputStream => R): R = JLine.usingTerminal { terminal =>
val in = terminal.wrapInIfNeeded(System.in)
try {
while (in.available > 0) in.read()
private[this] val isWin = Properties.isWin
private def drain(is: InputStream): Unit = while (is.available > 0) is.read()
private def withCharBufferedStdIn[R](f: InputStream => R): R =
if (!isWin) JLine.usingTerminal { terminal =>
terminal.init()
f(in)
} finally {
while (in.available > 0) in.read()
terminal.reset()
}
}
val in = terminal.wrapInIfNeeded(System.in)
try {
drain(in)
f(in)
} finally {
drain(in)
terminal.reset()
}
} else
try {
drain(System.in)
f(System.in)
} finally drain(System.in)
private[sbt] final val handleInput: InputStream => Action = in => {
@tailrec
def scanInput(): Action = {
if (in.available > 0) {
in.read() match {
case key if isEnter(key) => CancelWatch
case key if isR(key) => Trigger
case key if key >= 0 => scanInput()
case _ => Ignore
case key if isEnter(key) => CancelWatch
case key if isR(key) && !isWin => Trigger
case key if key >= 0 => scanInput()
case _ => Ignore
}
} else {
Ignore
@ -137,8 +144,9 @@ object Watched {
}
scanInput()
}
private[this] val reRun = if (isWin) "" else " or 'r' to re-run the command"
private def waitMessage(project: String): String =
s"Waiting for source changes$project... (press enter to interrupt or 'r' to re-run the command)"
s"Waiting for source changes$project... (press enter to interrupt$reRun)"
val defaultStartWatch: Int => Option[String] = count => Some(s"$count. ${waitMessage("")}")
@deprecated("Use defaultStartWatch in conjunction with the watchStartMessage key", "1.3.0")
val defaultWatchingMessage: WatchState => String = ws => defaultStartWatch(ws.count).get
@ -286,9 +294,8 @@ object Watched {
val terminationAction = watch(in, task, config)
config.onWatchTerminated(terminationAction, command, state)
} else {
config.logger.error(
s"Terminating watch due to invalid command(s): ${invalid.mkString("'", "', '", "'")}"
)
val commands = invalid.flatMap(_.left.toOption).mkString("'", "', '", "'")
config.logger.error(s"Terminating watch due to invalid command(s): $commands")
state.fail
}
}

View File

@ -23,9 +23,11 @@ private[sbt] object FileManagement {
// If the session is interactive or if the commands include a continuous build, then use
// the default configuration. Otherwise, use the sbt1_2_compat config, which does not cache
// anything, which makes it less likely to cause issues with CI.
val interactive = remaining.contains("shell") && !remaining.contains("setUpScripted")
val interactive = remaining.contains("shell") || remaining.lastOption.contains("iflast shell")
val scripted = remaining.contains("setUpScripted")
val continuous = remaining.exists(_.startsWith(ContinuousExecutePrefix))
if (interactive || continuous) {
if (!scripted && (interactive || continuous)) {
FileTreeViewConfig
.default(watchAntiEntropy.value, pollInterval.value, pollingDirectories.value)
} else FileTreeViewConfig.sbt1_2_compat(pollInterval.value, watchAntiEntropy.value)