Skip to content

Commit

Permalink
preserve prompt header for final render during shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
lihaoyi committed Sep 19, 2024
1 parent 7fda88f commit 4c5efd5
Showing 1 changed file with 18 additions and 9 deletions.
27 changes: 18 additions & 9 deletions main/util/src/mill/util/MultilinePromptLogger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private[mill] class MultilinePromptLogger(
)

override def close(): Unit = {
state.refreshPrompt()
state.refreshPrompt(ending = true)
stopped = true
}

Expand Down Expand Up @@ -130,15 +130,19 @@ private object MultilinePromptLogger {
(AnsiNav.clearScreen(0) + AnsiNav.left(9999)).getBytes
private var currentPromptBytes: Array[Byte] = Array[Byte]()

private def updatePromptBytes() = {
private def updatePromptBytes(ending: Boolean = false) = {
val now = System.currentTimeMillis()
for (k <- statuses.keySet) {
val removedTime = statuses(k).removedTimeMillis
if (removedTime != -1 && now - removedTime > statusRemovalDelayMillis) {
if (removedTime != -1 && now - removedTime > statusRemovalDelayMillis){
statuses.remove(k)
}
}

// For the ending prompt, make sure we clear out all
// the statuses to only show the header alone
if (ending) statuses.clear()

// -1 to leave a bit of buffer
val maxWidth = ConsoleDim.width() - 1
// -2 to account for 1 line header and 1 line `more threads`
Expand All @@ -162,10 +166,15 @@ private object MultilinePromptLogger {

val currentPrompt = header :: body
val currentHeight = body.length + 1
currentPromptBytes =
(AnsiNav.clearScreen(0) + currentPrompt.mkString("\n") + "\n" + AnsiNav.up(
currentHeight
)).getBytes
// For the ending prompt, leave the cursor at the bottom rather than scrolling back up.
// We do not want further output to overwrite the header as it will no longer re-render
val backUp = if (ending) "" else AnsiNav.up(currentHeight)
currentPromptBytes = (
AnsiNav.clearScreen(0) +
currentPrompt.mkString("\n") +
"\n" +
backUp
).getBytes
}

def updateGlobal(s: String): Unit = synchronized {
Expand All @@ -190,8 +199,8 @@ private object MultilinePromptLogger {
res
}

def refreshPrompt(): Unit = synchronized {
updatePromptBytes()
def refreshPrompt(ending: Boolean = false): Unit = synchronized {
updatePromptBytes(ending)
if (enableTicker) systemStreams0.err.write(currentPromptBytes)
}

Expand Down

0 comments on commit 4c5efd5

Please sign in to comment.