From 9e0cd4cde69c62dbfdd848f863edd7dcf29d26f7 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Fri, 25 Sep 2020 10:32:58 -0700 Subject: [PATCH] Clear prompt only if there are no bytes pending When sbt is running a background process that logs to stdout, the output can be inadvertently deleted before it has been printed. When the user is in the prompt state and a log message comes in, we want to delete the prompt before we print the log. The problem is println is often implemented with a write of the content followed by a second write of the system line separator. When that happened, we would print the content and then immediately delete it when the newline came in. The fix is to not clear the prompt if there are any bytes that have been written without a newline, which was tracked by the currentLineBytes variable. --- .../src/main/scala/sbt/internal/util/ProgressState.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/ProgressState.scala b/internal/util-logging/src/main/scala/sbt/internal/util/ProgressState.scala index 8c92e1be3..329cd6ad8 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/ProgressState.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/ProgressState.scala @@ -72,8 +72,7 @@ private[sbt] final class ProgressState( if (!lines.endsWith(System.lineSeparator)) { val allLines = lines.split(System.lineSeparator) allLines.dropRight(1).foreach(appendLine) - allLines.lastOption - .foreach(currentLineBytes.get ++= _.getBytes("UTF-8")) + allLines.lastOption.foreach(currentLineBytes.get ++= _.getBytes("UTF-8")) } else if (lines.contains(System.lineSeparator)) { lines.split(System.lineSeparator).foreach(appendLine) } @@ -92,11 +91,12 @@ private[sbt] final class ProgressState( printStream: PrintStream, hasProgress: Boolean ): Unit = { + val canClearPrompt = currentLineBytes.get.isEmpty addBytes(terminal, bytes) if (hasProgress) { val toWrite = new ArrayBuffer[Byte] terminal.prompt match { - case a: Prompt.AskUser if a.render.nonEmpty => + case a: Prompt.AskUser if a.render.nonEmpty && canClearPrompt => toWrite ++= (DeleteLine + ClearScreenAfterCursor + CursorLeft1000).getBytes("UTF-8") case _ => }