mirror of https://github.com/sbt/sbt.git
Add reprompt fast track command
With the latest sbt snapshot, the ui would get stuck if the user entered
an empty command. They would be presented with an empty prompt and could
not input any commands. This was caused by the change in
d569abe70a that reset the prompt after a
line was read. I had tried to optimize line reading by ignoring empty
commands in UITask.readline so we wouldn't have to make a new thread.
This optimization wasn't really buying much since it only affects how
quickly the user is reprompted after entering an empty command. Unless a
user is spamming the <enter> key, they shouldn't notice a difference.
This commit is contained in:
parent
31bea086aa
commit
adc8d5ee6e
|
|
@ -74,13 +74,13 @@ object LineReader {
|
||||||
parser: Parser[_],
|
parser: Parser[_],
|
||||||
terminal: Terminal,
|
terminal: Terminal,
|
||||||
): LineReader = {
|
): LineReader = {
|
||||||
val term = JLine3(terminal)
|
|
||||||
// We may want to consider insourcing LineReader.java from jline. We don't otherwise
|
// We may want to consider insourcing LineReader.java from jline. We don't otherwise
|
||||||
// directly need jline3 for sbt.
|
// directly need jline3 for sbt.
|
||||||
val reader = LineReaderBuilder.builder().terminal(term).completer(completer(parser)).build()
|
|
||||||
historyPath.foreach(f => reader.setVariable(JLineReader.HISTORY_FILE, f))
|
|
||||||
new LineReader {
|
new LineReader {
|
||||||
override def readLine(prompt: String, mask: Option[Char]): Option[String] = {
|
override def readLine(prompt: String, mask: Option[Char]): Option[String] = {
|
||||||
|
val term = JLine3(terminal)
|
||||||
|
val reader = LineReaderBuilder.builder().terminal(term).completer(completer(parser)).build()
|
||||||
|
historyPath.foreach(f => reader.setVariable(JLineReader.HISTORY_FILE, f))
|
||||||
try terminal.withRawInput {
|
try terminal.withRawInput {
|
||||||
Option(mask.map(reader.readLine(prompt, _)).getOrElse(reader.readLine(prompt)))
|
Option(mask.map(reader.readLine(prompt, _)).getOrElse(reader.readLine(prompt)))
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ private[sbt] object UITask {
|
||||||
def readLine(): Either[String, String] =
|
def readLine(): Either[String, String] =
|
||||||
try {
|
try {
|
||||||
val clear = terminal.ansi(ClearPromptLine, "")
|
val clear = terminal.ansi(ClearPromptLine, "")
|
||||||
@tailrec def impl(): Either[String, String] = {
|
val res = {
|
||||||
val thread = Thread.currentThread
|
val thread = Thread.currentThread
|
||||||
if (thread.isInterrupted || closed.get) throw interrupted
|
if (thread.isInterrupted || closed.get) throw interrupted
|
||||||
val reader = LineReader.createReader(history(state), parser, terminal)
|
val reader = LineReader.createReader(history(state), parser, terminal)
|
||||||
|
|
@ -76,16 +76,17 @@ private[sbt] object UITask {
|
||||||
case None => Left(TerminateAction)
|
case None => Left(TerminateAction)
|
||||||
case Some(s: String) =>
|
case Some(s: String) =>
|
||||||
s.trim() match {
|
s.trim() match {
|
||||||
case "" => impl()
|
// We need to put the empty string on the fast track queue so that we can
|
||||||
|
// reprompt the user if another command is running on the server.
|
||||||
|
case "" => Left("")
|
||||||
case cmd @ (`Shutdown` | `TerminateAction` | `Cancel`) => Left(cmd)
|
case cmd @ (`Shutdown` | `TerminateAction` | `Cancel`) => Left(cmd)
|
||||||
case cmd => Right(cmd)
|
case cmd => Right(cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val res = impl()
|
|
||||||
terminal.setPrompt(Prompt.Pending)
|
terminal.setPrompt(Prompt.Pending)
|
||||||
res
|
res
|
||||||
} catch { case e: InterruptedException => Right("") }
|
} catch { case e: InterruptedException => Left("") }
|
||||||
override def close(): Unit = closed.set(true)
|
override def close(): Unit = closed.set(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -446,7 +446,7 @@ private[sbt] final class CommandExchange {
|
||||||
case null =>
|
case null =>
|
||||||
case mt: FastTrackTask =>
|
case mt: FastTrackTask =>
|
||||||
mt.task match {
|
mt.task match {
|
||||||
case `attach` => mt.channel.prompt(ConsolePromptEvent(lastState.get))
|
case `attach` | "" => mt.channel.prompt(ConsolePromptEvent(lastState.get))
|
||||||
case `Cancel` =>
|
case `Cancel` =>
|
||||||
Option(currentExecRef.get).foreach(cancel)
|
Option(currentExecRef.get).foreach(cancel)
|
||||||
mt.channel.prompt(ConsolePromptEvent(lastState.get))
|
mt.channel.prompt(ConsolePromptEvent(lastState.get))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue