Merge pull request #6129 from eatkins/bsp-watch-fix

Fix watch when metals sbt bsp is in use
This commit is contained in:
Ethan Atkins 2020-11-20 08:20:53 -08:00 committed by GitHub
commit dc10abfa30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 18 deletions

View File

@ -31,31 +31,33 @@ private[sbt] class UserThread(val channel: CommandChannel) extends AutoCloseable
private[sbt] def reset(state: State): Unit = if (!isClosed.get) { private[sbt] def reset(state: State): Unit = if (!isClosed.get) {
uiThread.synchronized { uiThread.synchronized {
val task = channel.makeUIThread(state) val task = channel.makeUIThread(state)
def submit(): Thread = { def submit(): Unit = {
val thread: Thread = new Thread(s"sbt-$name-ui-thread") { val thread: Thread = new Thread(s"sbt-$name-ui-thread") {
setDaemon(true) setDaemon(true)
override def run(): Unit = override def run(): Unit =
try task.run() try task.run()
finally uiThread.get match { finally {
case (_, t) if t == this => uiThread.set(null) uiThread.getAndSet(null) match {
case _ => case prev @ (_, th) if th != this => uiThread.set(prev)
case _ =>
}
} }
} }
uiThread.getAndSet((task, thread)) match { uiThread.getAndSet((task, thread)) match {
case null => thread.start() case null => thread.start()
case (task, t) if t.getClass != task.getClass => case (prevTask, prevThread) if prevTask.getClass != task.getClass =>
stopThreadImpl() prevTask.close()
prevThread.joinFor(1.second)
thread.start() thread.start()
case t => uiThread.set(t) case t => uiThread.set(t)
} }
thread
} }
uiThread.get match { uiThread.get match {
case null => uiThread.set((task, submit())) case null => submit()
case (t, _) if t.getClass == task.getClass => case (prevTask, _) if prevTask.getClass == task.getClass =>
case (t, thread) => case (t, thread) =>
stopThreadImpl() stopThreadImpl()
uiThread.set((task, submit())) submit()
} }
} }
Option(lastProgressEvent.get).foreach(onProgressEvent) Option(lastProgressEvent.get).foreach(onProgressEvent)

View File

@ -992,12 +992,19 @@ object BuiltinCommands {
val exchange = StandardMain.exchange val exchange = StandardMain.exchange
exchange.channelForName(channel) match { exchange.channelForName(channel) match {
case Some(c) if ContinuousCommands.isInWatch(s0, c) => 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 s1 = exchange.run(s0)
val exec: Exec = getExec(s1, Duration.Inf) val exec: Exec = getExec(s1, Duration.Inf)
val remaining: List[Exec] = val remaining: List[Exec] =
Exec(s"${ContinuousCommands.waitWatch} $channel", None) :: Exec(FailureWall, None) :: Exec(s"${ContinuousCommands.waitWatch} $channel", None) ::
Exec(FailureWall, None) :: s1.remainingCommands s1.remainingCommands
val newState = s1.copy(remainingCommands = exec +: remaining) val newState = s1.copy(remainingCommands = exec +: remaining)
if (exec.commandLine.trim.isEmpty) newState if (exec.commandLine.trim.isEmpty) newState
else newState.clearGlobalLog else newState.clearGlobalLog

View File

@ -226,9 +226,8 @@ object MainLoop {
// 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) if (c.terminal.prompt != Prompt.Watch) c.terminal.setPrompt(prevPrompt)
ITerminal.set(prevTerminal) ITerminal.set(prevTerminal)
c.terminal.setPrompt(prevPrompt)
c.terminal.flush() c.terminal.flush()
}) -> progressState.put(Keys.terminalKey, Terminal(c.terminal)) }) -> progressState.put(Keys.terminalKey, Terminal(c.terminal))
case _ => (() => ()) -> progressState.put(Keys.terminalKey, Terminal(ITerminal.get)) case _ => (() => ()) -> progressState.put(Keys.terminalKey, Terminal(ITerminal.get))

View File

@ -1344,8 +1344,7 @@ private[sbt] object ContinuousCommands {
private[sbt] val postWatchCommand = watchCommand(postWatch) { (channel, state) => private[sbt] val postWatchCommand = watchCommand(postWatch) { (channel, state) =>
val cs = watchState(state, channel) val cs = watchState(state, channel)
StandardMain.exchange.channelForName(channel).foreach { c => StandardMain.exchange.channelForName(channel).foreach { c =>
c.terminal.setPrompt(Prompt.Watch) c.terminal.setPrompt(Prompt.Pending)
c.unprompt(ConsoleUnpromptEvent(Some(CommandSource(channel))))
} }
val postState = state.get(watchStates) match { val postState = state.get(watchStates) match {
case None => state case None => state
@ -1360,7 +1359,10 @@ private[sbt] object ContinuousCommands {
cs.callbacks.onExit() cs.callbacks.onExit()
StandardMain.exchange StandardMain.exchange
.channelForName(channel) .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 { afterWatchState.get(watchStates) match {
case None => afterWatchState case None => afterWatchState
case Some(w) => afterWatchState.put(watchStates, w - channel) case Some(w) => afterWatchState.put(watchStates, w - channel)