Skip to content

Commit

Permalink
Update terminal width when progress animation is updated (#463)
Browse files Browse the repository at this point in the history
Without updating the terminal width for each progress update, a progress line may be printed as more than one line, so line clearing will not work as expected and many lines will be printed when overflowing max columns of line.

Ninja also checks the terminal width every line print: https://github.com/ninja-build/ninja/blob/fd7067652cae480190bf13b2ee5475efdf09ac7d/src/line_printer.cc#L110

This particularly improves the build and test progress report of SwiftPM.

**Before**

https://github.com/apple/swift-tools-support-core/assets/11702759/7c32c2d5-0469-479b-a542-6ffd0656610a

**After**

https://github.com/apple/swift-tools-support-core/assets/11702759/71e6ce59-f888-4a19-819a-3012c9ea378f
  • Loading branch information
kateinoigakukun authored Feb 5, 2024
1 parent 397343f commit 9595fce
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 14 deletions.
16 changes: 8 additions & 8 deletions Sources/TSCBasic/TerminalController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ public final class TerminalController {
private var stream: WritableByteStream

/// Width of the terminal.
public let width: Int
public var width: Int {
// Determine the terminal width otherwise assume a default.
if let terminalWidth = TerminalController.terminalWidth(), terminalWidth > 0 {
return terminalWidth
} else {
return 80
}
}

/// Code to clear the line on a tty.
private let clearLineString = "\u{001B}[2K"
Expand All @@ -84,13 +91,6 @@ public final class TerminalController {
return nil
}

// Determine the terminal width otherwise assume a default.
if let terminalWidth = TerminalController.terminalWidth(), terminalWidth > 0 {
width = terminalWidth
} else {
width = 80
}

#if os(Windows)
// Enable VT100 interpretation
let hOut = GetStdHandle(STD_OUTPUT_HANDLE)
Expand Down
14 changes: 8 additions & 6 deletions Sources/TSCUtility/ProgressAnimation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,10 @@ public final class RedrawingNinjaProgressAnimation: ProgressAnimationProtocol {
terminal.clearLine()

let progressText = "[\(step)/\(total)] \(text)"
if progressText.utf8.count > terminal.width {
let width = terminal.width
if progressText.utf8.count > width {
let suffix = ""
terminal.write(String(progressText.prefix(terminal.width - suffix.utf8.count)))
terminal.write(String(progressText.prefix(width - suffix.utf8.count)))
terminal.write(suffix)
} else {
terminal.write(progressText)
Expand Down Expand Up @@ -211,8 +212,9 @@ public final class RedrawingLitProgressAnimation: ProgressAnimationProtocol {
public func update(step: Int, total: Int, text: String) {
assert(step <= total)

let width = terminal.width
if !hasDisplayedHeader {
let spaceCount = terminal.width / 2 - header.utf8.count / 2
let spaceCount = width / 2 - header.utf8.count / 2
terminal.write(repeating(string: " ", count: spaceCount))
terminal.write(header, inColor: .cyan, bold: true)
terminal.endLine()
Expand All @@ -225,18 +227,18 @@ public final class RedrawingLitProgressAnimation: ProgressAnimationProtocol {
let prefix = "\(paddedPercentage)% " + terminal.wrap("[", inColor: .green, bold: true)
terminal.write(prefix)

let barWidth = terminal.width - prefix.utf8.count
let barWidth = width - prefix.utf8.count
let n = Int(Double(barWidth) * Double(percentage) / 100.0)

terminal.write(repeating(string: "=", count: n) + repeating(string: "-", count: barWidth - n), inColor: .green)
terminal.write("]", inColor: .green, bold: true)
terminal.endLine()

terminal.clearLine()
if text.utf8.count > terminal.width {
if text.utf8.count > width {
let prefix = ""
terminal.write(prefix)
terminal.write(String(text.suffix(terminal.width - prefix.utf8.count)))
terminal.write(String(text.suffix(width - prefix.utf8.count)))
} else {
terminal.write(text)
}
Expand Down

0 comments on commit 9595fce

Please sign in to comment.