From 6da6fc58600305d13461d6942e2d0f1c9c997efe Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 3 Feb 2024 08:51:57 +0000 Subject: [PATCH] Update terminal width when progress animation is updated Without updating the terminal width, 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. --- Sources/TSCBasic/TerminalController.swift | 16 ++++++++-------- Sources/TSCUtility/ProgressAnimation.swift | 14 ++++++++------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Sources/TSCBasic/TerminalController.swift b/Sources/TSCBasic/TerminalController.swift index 19556e58..e7b9bf6f 100644 --- a/Sources/TSCBasic/TerminalController.swift +++ b/Sources/TSCBasic/TerminalController.swift @@ -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" @@ -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) diff --git a/Sources/TSCUtility/ProgressAnimation.swift b/Sources/TSCUtility/ProgressAnimation.swift index c0383531..ced8c27b 100644 --- a/Sources/TSCUtility/ProgressAnimation.swift +++ b/Sources/TSCUtility/ProgressAnimation.swift @@ -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) @@ -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() @@ -225,7 +227,7 @@ 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) @@ -233,10 +235,10 @@ public final class RedrawingLitProgressAnimation: ProgressAnimationProtocol { 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) }