mirror of https://github.com/sbt/sbt.git
Fix watch with metals sbt bsp implementation
I discovered that the metals bsp implementation worked very badly with continuous builds. The problem was that metals is able to trigger a bsp compile slightly before the continuous build would trigger. This would cause the ui to get in a bad state. The worst case was that it would actually cause sbt (or the thin client) to exit. A less catastrophic issue was that it was possible for the wrong count to be printed by the continuous message. This commit fixes the issue by more carefully managing the prompt state and only resetting the ui when the prompt is not in the Prompt.Watch state.
This commit is contained in:
parent
68933a628d
commit
600628e8e9
|
|
@ -990,12 +990,19 @@ object BuiltinCommands {
|
|||
val exchange = StandardMain.exchange
|
||||
exchange.channelForName(channel) match {
|
||||
case Some(c) if ContinuousCommands.isInWatch(s0, c) =>
|
||||
c.prompt(ConsolePromptEvent(s0))
|
||||
if (c.terminal.prompt != Prompt.Watch) {
|
||||
c.terminal.setPrompt(Prompt.Watch)
|
||||
c.prompt(ConsolePromptEvent(s0))
|
||||
} else if (c.terminal.isSupershellEnabled) {
|
||||
c.terminal.printStream.print(ConsoleAppender.ClearScreenAfterCursor)
|
||||
c.terminal.printStream.flush()
|
||||
}
|
||||
|
||||
val s1 = exchange.run(s0)
|
||||
val exec: Exec = getExec(s1, Duration.Inf)
|
||||
val remaining: List[Exec] =
|
||||
Exec(s"${ContinuousCommands.waitWatch} $channel", None) ::
|
||||
Exec(FailureWall, None) :: s1.remainingCommands
|
||||
Exec(FailureWall, None) :: Exec(s"${ContinuousCommands.waitWatch} $channel", None) ::
|
||||
s1.remainingCommands
|
||||
val newState = s1.copy(remainingCommands = exec +: remaining)
|
||||
if (exec.commandLine.trim.isEmpty) newState
|
||||
else newState.clearGlobalLog
|
||||
|
|
|
|||
|
|
@ -226,9 +226,8 @@ object MainLoop {
|
|||
// temporarily set the prompt to running during task evaluation
|
||||
c.terminal.setPrompt(Prompt.Running)
|
||||
(() => {
|
||||
c.terminal.setPrompt(prevPrompt)
|
||||
if (c.terminal.prompt != Prompt.Watch) c.terminal.setPrompt(prevPrompt)
|
||||
ITerminal.set(prevTerminal)
|
||||
c.terminal.setPrompt(prevPrompt)
|
||||
c.terminal.flush()
|
||||
}) -> progressState.put(Keys.terminalKey, Terminal(c.terminal))
|
||||
case _ => (() => ()) -> progressState.put(Keys.terminalKey, Terminal(ITerminal.get))
|
||||
|
|
|
|||
|
|
@ -1344,8 +1344,7 @@ private[sbt] object ContinuousCommands {
|
|||
private[sbt] val postWatchCommand = watchCommand(postWatch) { (channel, state) =>
|
||||
val cs = watchState(state, channel)
|
||||
StandardMain.exchange.channelForName(channel).foreach { c =>
|
||||
c.terminal.setPrompt(Prompt.Watch)
|
||||
c.unprompt(ConsoleUnpromptEvent(Some(CommandSource(channel))))
|
||||
c.terminal.setPrompt(Prompt.Pending)
|
||||
}
|
||||
val postState = state.get(watchStates) match {
|
||||
case None => state
|
||||
|
|
@ -1360,7 +1359,10 @@ private[sbt] object ContinuousCommands {
|
|||
cs.callbacks.onExit()
|
||||
StandardMain.exchange
|
||||
.channelForName(channel)
|
||||
.foreach(_.unprompt(ConsoleUnpromptEvent(Some(CommandSource(channel)))))
|
||||
.foreach { c =>
|
||||
c.terminal.setPrompt(Prompt.Pending)
|
||||
c.unprompt(ConsoleUnpromptEvent(Some(CommandSource(channel))))
|
||||
}
|
||||
afterWatchState.get(watchStates) match {
|
||||
case None => afterWatchState
|
||||
case Some(w) => afterWatchState.put(watchStates, w - channel)
|
||||
|
|
|
|||
Loading…
Reference in New Issue