mirror of https://github.com/sbt/sbt.git
Merge pull request #6129 from eatkins/bsp-watch-fix
Fix watch when metals sbt bsp is in use
This commit is contained in:
commit
dc10abfa30
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue