Fix supershell blowing away lines on windows

In 85d17889b6, I attempted to fix
supershell messages getting interlaced with log lines. It turned out
that that approach didn't work with windows and was causing all of the
output to bet blown away. A better approach is to check if the bytes
we're writing contain one or more line separators. If so, we can wrap
the bytes in a string and split the string into lines. Then we can
append a ClearScreenAfterCursor before every newline.

I think the problem with windows was that the ClearScreenAfterCursor was
coming between the carraige return and the newline.
This commit is contained in:
Ethan Atkins 2020-11-18 13:26:07 -08:00
parent 1ea0fb7d23
commit f3120f8f15
1 changed files with 19 additions and 10 deletions

View File

@ -85,6 +85,9 @@ private[sbt] final class ProgressState(
prefix.getBytes ++ terminal.prompt.render().getBytes("UTF-8")
} else Array.empty
}
private[this] val cleanPrompt =
(DeleteLine + ClearScreenAfterCursor + CursorLeft1000).getBytes("UTF-8")
private[this] val clearScreenBytes = ClearScreenAfterCursor.getBytes("UTF-8")
private[util] def write(
terminal: Terminal,
bytes: Array[Byte],
@ -96,23 +99,29 @@ private[sbt] final class ProgressState(
addBytes(terminal, bytes)
val toWrite = new ArrayBuffer[Byte]
terminal.prompt match {
case a: Prompt.AskUser if a.render.nonEmpty && canClearPrompt =>
toWrite ++= (DeleteLine + ClearScreenAfterCursor + CursorLeft1000).getBytes("UTF-8")
case _ =>
case a: Prompt.AskUser if a.render.nonEmpty && canClearPrompt => toWrite ++= cleanPrompt
case _ =>
}
bytes.foreach { b =>
if (b == 10) toWrite ++= ClearScreenAfterCursor.getBytes("UTF-8")
toWrite += b
}
toWrite ++= ClearScreenAfterCursor.getBytes("UTF-8")
if (bytes.endsWith(lineSeparatorBytes)) {
val endsWithNewLine = bytes.endsWith(lineSeparatorBytes)
if (endsWithNewLine || bytes.containsSlice(lineSeparatorBytes)) {
val parts = new String(bytes, "UTF-8").split(System.lineSeparator)
def appendLine(l: String, appendNewline: Boolean): Unit = {
toWrite ++= l.getBytes("UTF-8")
toWrite ++= clearScreenBytes
if (appendNewline) toWrite ++= lineSeparatorBytes
}
parts.dropRight(1).foreach(appendLine(_, true))
parts.lastOption.foreach(appendLine(_, bytes.endsWith(lineSeparatorBytes)))
} else toWrite ++= bytes
toWrite ++= clearScreenBytes
if (endsWithNewLine) {
if (progressLines.get.nonEmpty) {
val lastLine = terminal.prompt match {
case a: Prompt.AskUser => a.render()
case _ => currentLine.getOrElse("")
}
val lines = printProgress(terminal, lastLine)
toWrite ++= (ClearScreenAfterCursor + lines).getBytes("UTF-8")
toWrite ++= lines.getBytes("UTF-8")
}
toWrite ++= getPrompt(terminal)
}