From 0a8a982a243f4ed768b0138c747bde0d32dd2a52 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Tue, 7 Jan 2025 21:31:47 +0100 Subject: [PATCH 1/9] extra ASCII compatible styles added --- .../ActivityIndicator+CommandArgument.swift | 9 ++++ Sources/ActivityIndicator.swift | 42 +++++++++++++++++++ Sources/ProgressLine.swift | 2 +- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/Sources/ActivityIndicator+CommandArgument.swift b/Sources/ActivityIndicator+CommandArgument.swift index 70633eb..b1f9b1b 100644 --- a/Sources/ActivityIndicator+CommandArgument.swift +++ b/Sources/ActivityIndicator+CommandArgument.swift @@ -4,6 +4,9 @@ enum ActivityIndicatorStyle: String, CaseIterable, ExpressibleByArgument { case dots case kitt case snake + case spinner + case wave + case bounce } extension ActivityIndicator { @@ -15,6 +18,12 @@ extension ActivityIndicator { .kitt case .snake: .snake + case .spinner: + .spinner + case .wave: + .wave + case .bounce: + .bounce } } } diff --git a/Sources/ActivityIndicator.swift b/Sources/ActivityIndicator.swift index 3a75a62..0bea429 100644 --- a/Sources/ActivityIndicator.swift +++ b/Sources/ActivityIndicator.swift @@ -76,6 +76,48 @@ extension ActivityIndicator { ) return ActivityIndicator(configuration: configuration) }() + + static let spinner: ActivityIndicator = { + let configuration = Configuration( + refreshRate: 125, + states: [ + "\\", + "|", + "/", + "-", + ] + ) + return ActivityIndicator(configuration: configuration) + }() + + static let wave: ActivityIndicator = { + let configuration = Configuration( + refreshRate: 125, + states: [ + "o...", + "Oo..", + "oOo.", + ".oOo", + "..oO", + "...o", + ] + ) + return ActivityIndicator(configuration: configuration) + }() + + static let bounce: ActivityIndicator = { + let configuration = Configuration( + refreshRate: 125, + states: [ + ".", + "o", + "O", + "o", + ".", + ] + ) + return ActivityIndicator(configuration: configuration) + }() } #if DEBUG diff --git a/Sources/ProgressLine.swift b/Sources/ProgressLine.swift index 27ea90e..eb83b1a 100644 --- a/Sources/ProgressLine.swift +++ b/Sources/ProgressLine.swift @@ -16,7 +16,7 @@ struct ProgressLine: AsyncParsableCommand { var staticText: String? @Option(name: [.customLong("activity-style"), .customShort("s")], help: "The style of the activity indicator.") - var activityIndicatorStyle: ActivityIndicatorStyle = .dots + var activityIndicatorStyle: ActivityIndicatorStyle = .spinner @Option(name: [.customLong("original-log-path"), .customShort("l")], help: "Save the original log to a file.") var originalLogPath: String? From d0d6c5cc4631c27b6f5783a3df85c87eaa9e1e72 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 15:03:09 +0100 Subject: [PATCH 2/9] custom styles by yaml file --- Package.swift | 2 + Sources/ActivityConfiguration.swift | 25 +++++++++ .../ActivityIndicator+CommandArgument.swift | 54 +++++++++++++------ Sources/ProgressLine.swift | 5 +- custom-styles.yml | 26 +++++++++ 5 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 Sources/ActivityConfiguration.swift create mode 100644 custom-styles.yml diff --git a/Package.swift b/Package.swift index 2d8303d..50f7fb6 100644 --- a/Package.swift +++ b/Package.swift @@ -15,6 +15,7 @@ let package = Package( .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"), .package(url: "https://github.com/pointfreeco/swift-tagged.git", from: "0.10.0"), .package(url: "https://github.com/pointfreeco/swift-concurrency-extras.git", from: "1.1.0"), + .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.6"), ], targets: [ .executableTarget( @@ -23,6 +24,7 @@ let package = Package( .product(name: "ArgumentParser", package: "swift-argument-parser"), .product(name: "TaggedTime", package: "swift-tagged"), .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), + .product(name: "Yams", package: "Yams"), ], swiftSettings: [ .enableExperimentalFeature("StrictConcurrency"), ] diff --git a/Sources/ActivityConfiguration.swift b/Sources/ActivityConfiguration.swift new file mode 100644 index 0000000..d6f4644 --- /dev/null +++ b/Sources/ActivityConfiguration.swift @@ -0,0 +1,25 @@ +import Foundation +import Yams + +struct ActivityStyleConfig: Codable { + let name: String + let refreshRate: UInt64 + let states: [String] +} + +struct ActivityConfiguration { + static func loadConfiguration(from path: String) throws -> [ActivityStyleConfig] { + let url = URL(fileURLWithPath: path) + let yamlString = try String(contentsOf: url, encoding: .utf8) + let decoder = YAMLDecoder() + return try decoder.decode([ActivityStyleConfig].self, from: yamlString) + } + + static func createActivityIndicator(from config: ActivityStyleConfig) -> ActivityIndicator { + let configuration = ActivityIndicator.Configuration( + refreshRate: Milliseconds(config.refreshRate), + states: config.states + ) + return ActivityIndicator(configuration: configuration) + } +} \ No newline at end of file diff --git a/Sources/ActivityIndicator+CommandArgument.swift b/Sources/ActivityIndicator+CommandArgument.swift index b1f9b1b..c6d89ff 100644 --- a/Sources/ActivityIndicator+CommandArgument.swift +++ b/Sources/ActivityIndicator+CommandArgument.swift @@ -1,29 +1,53 @@ import ArgumentParser -enum ActivityIndicatorStyle: String, CaseIterable, ExpressibleByArgument { +enum ActivityIndicatorStyle: ExpressibleByArgument { case dots case kitt case snake case spinner case wave case bounce + case custom(String) + + init?(argument: String) { + switch argument { + case "dots": self = .dots + case "kitt": self = .kitt + case "snake": self = .snake + case "spinner": self = .spinner + case "wave": self = .wave + case "bounce": self = .bounce + default: self = .custom(argument) + } + } + + static var allCases: [String] { + ["dots", "kitt", "snake", "spinner", "wave", "bounce"] + } } extension ActivityIndicator { - static func make(style: ActivityIndicatorStyle) -> ActivityIndicator { + static func make(style: ActivityIndicatorStyle, configPath: String?) -> ActivityIndicator { + if case let .custom(styleName) = style, let configPath = configPath { + do { + let configs = try ActivityConfiguration.loadConfiguration(from: configPath) + if let matchingConfig = configs.first(where: { $0.name == styleName }) { + return ActivityConfiguration.createActivityIndicator(from: matchingConfig) + } + } catch { + print("Warning: Failed to load custom style '\(styleName)' from config: \(error)") + } + } + + // Fallback to built-in styles switch style { - case .dots: - .dots - case .kitt: - .kitt - case .snake: - .snake - case .spinner: - .spinner - case .wave: - .wave - case .bounce: - .bounce + case .dots: return .dots + case .kitt: return .kitt + case .snake: return .snake + case .spinner: return .spinner + case .wave: return .wave + case .bounce: return .bounce + case .custom(_): return .spinner // Default to spinner if custom style fails to load } } -} +} \ No newline at end of file diff --git a/Sources/ProgressLine.swift b/Sources/ProgressLine.swift index eb83b1a..867ce80 100644 --- a/Sources/ProgressLine.swift +++ b/Sources/ProgressLine.swift @@ -15,9 +15,12 @@ struct ProgressLine: AsyncParsableCommand { @Option(name: [.long, .customShort("t")], help: "The static text to display instead of the latest stdin data.") var staticText: String? - @Option(name: [.customLong("activity-style"), .customShort("s")], help: "The style of the activity indicator.") + @Option(name: [.customLong("activity-style"), .customShort("s")], help: "The style of the activity indicator (built-in or custom).") var activityIndicatorStyle: ActivityIndicatorStyle = .spinner + @Option(name: [.customLong("config-path"), .customShort("c")], help: "Path to the activity styles configuration file.") + var configPath: String? + @Option(name: [.customLong("original-log-path"), .customShort("l")], help: "Save the original log to a file.") var originalLogPath: String? diff --git a/custom-styles.yml b/custom-styles.yml new file mode 100644 index 0000000..f8f3d15 --- /dev/null +++ b/custom-styles.yml @@ -0,0 +1,26 @@ +# Built-in like animation with hearts +- name: hearts + refreshRate: 125 # milliseconds between states + states: + - 💗 + - 💓 + - 💝 + - 💓 + +# Arrow animation with longer refresh rate +- name: arrows + refreshRate: 150 + states: + - → + - ⇒ + - âŸč + - ⇒ + +# Matrix-style falling characters +- name: matrix + refreshRate: 100 + states: + - "âŁŸâ ż" + - "âŁœâ ż" + - "⣻⠿" + - "âążâ ż" \ No newline at end of file From f897a3b3af7129007ea5da6090dce81e275acd46 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 15:23:05 +0100 Subject: [PATCH 3/9] removed static styles --- Package.resolved | 11 +++++- Sources/ActivityConfiguration.swift | 1 + .../ActivityIndicator+CommandArgument.swift | 11 ++---- Sources/ActivityIndicator.swift | 29 -------------- Sources/ProgressLine.swift | 4 +- custom-styles.yml | 39 ++++++++++++++----- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/Package.resolved b/Package.resolved index f0e739d..ee34bc3 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "e759c45271facbb3650829c703702a2ac4817adf75a8116cc3d77eae8e3d3bae", + "originHash" : "541a757caafbe47ca9354751ce6a36bcabcc1fb6755f04009a4f675dfe6cb0ad", "pins" : [ { "identity" : "swift-argument-parser", @@ -27,6 +27,15 @@ "revision" : "3907a9438f5b57d317001dc99f3f11b46882272b", "version" : "0.10.0" } + }, + { + "identity" : "yams", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jpsim/Yams.git", + "state" : { + "revision" : "3036ba9d69cf1fd04d433527bc339dc0dc75433d", + "version" : "5.1.3" + } } ], "version" : 3 diff --git a/Sources/ActivityConfiguration.swift b/Sources/ActivityConfiguration.swift index d6f4644..6d434bc 100644 --- a/Sources/ActivityConfiguration.swift +++ b/Sources/ActivityConfiguration.swift @@ -1,5 +1,6 @@ import Foundation import Yams +import TaggedTime struct ActivityStyleConfig: Codable { let name: String diff --git a/Sources/ActivityIndicator+CommandArgument.swift b/Sources/ActivityIndicator+CommandArgument.swift index c6d89ff..8dce245 100644 --- a/Sources/ActivityIndicator+CommandArgument.swift +++ b/Sources/ActivityIndicator+CommandArgument.swift @@ -1,12 +1,11 @@ import ArgumentParser +import TaggedTime enum ActivityIndicatorStyle: ExpressibleByArgument { case dots case kitt case snake case spinner - case wave - case bounce case custom(String) init?(argument: String) { @@ -15,14 +14,12 @@ enum ActivityIndicatorStyle: ExpressibleByArgument { case "kitt": self = .kitt case "snake": self = .snake case "spinner": self = .spinner - case "wave": self = .wave - case "bounce": self = .bounce default: self = .custom(argument) } } static var allCases: [String] { - ["dots", "kitt", "snake", "spinner", "wave", "bounce"] + ["dots", "kitt", "snake", "spinner"] } } @@ -35,7 +32,7 @@ extension ActivityIndicator { return ActivityConfiguration.createActivityIndicator(from: matchingConfig) } } catch { - print("Warning: Failed to load custom style '\(styleName)' from config: \(error)") + print("\(ANSI.yellow)[!] progressline: Failed to load custom style '\(styleName)' from config: \(error)\(ANSI.reset)") } } @@ -45,8 +42,6 @@ extension ActivityIndicator { case .kitt: return .kitt case .snake: return .snake case .spinner: return .spinner - case .wave: return .wave - case .bounce: return .bounce case .custom(_): return .spinner // Default to spinner if custom style fails to load } } diff --git a/Sources/ActivityIndicator.swift b/Sources/ActivityIndicator.swift index 0bea429..7534758 100644 --- a/Sources/ActivityIndicator.swift +++ b/Sources/ActivityIndicator.swift @@ -89,35 +89,6 @@ extension ActivityIndicator { ) return ActivityIndicator(configuration: configuration) }() - - static let wave: ActivityIndicator = { - let configuration = Configuration( - refreshRate: 125, - states: [ - "o...", - "Oo..", - "oOo.", - ".oOo", - "..oO", - "...o", - ] - ) - return ActivityIndicator(configuration: configuration) - }() - - static let bounce: ActivityIndicator = { - let configuration = Configuration( - refreshRate: 125, - states: [ - ".", - "o", - "O", - "o", - ".", - ] - ) - return ActivityIndicator(configuration: configuration) - }() } #if DEBUG diff --git a/Sources/ProgressLine.swift b/Sources/ProgressLine.swift index 867ce80..db2ec78 100644 --- a/Sources/ProgressLine.swift +++ b/Sources/ProgressLine.swift @@ -48,10 +48,10 @@ struct ProgressLine: AsyncParsableCommand { let logger = AboveProgressLineLogger(printers: printers) #if DEBUG - let activityIndicator: ActivityIndicator = testMode ? .disabled() : .make(style: activityIndicatorStyle) + let activityIndicator: ActivityIndicator = testMode ? .disabled() : .make(style: activityIndicatorStyle, configPath: configPath) #else let testMode = false - let activityIndicator: ActivityIndicator = .make(style: activityIndicatorStyle) + let activityIndicator: ActivityIndicator = .make(style: activityIndicatorStyle, configPath: configPath) #endif let progressLineController = await ProgressLineController.buildAndStart( textMode: staticText.map { .staticText($0) } ?? .stdin, diff --git a/custom-styles.yml b/custom-styles.yml index f8f3d15..a4f380f 100644 --- a/custom-styles.yml +++ b/custom-styles.yml @@ -11,16 +11,37 @@ - name: arrows refreshRate: 150 states: - - → - - ⇒ - - âŸč - - ⇒ + - "→" + - "⇒" + - "âŸč" + - "⇒" # Matrix-style falling characters -- name: matrix +- name: blocks refreshRate: 100 states: - - "âŁŸâ ż" - - "âŁœâ ż" - - "⣻⠿" - - "âążâ ż" \ No newline at end of file + - "▒ " + - "▓ " + - "█ " + - "█░ " + - "█▒ " + - "█▓ " + - "██ " + - "██░" + - "██▒" + - "██▓" + - "███" + - "░ " + +# Contruct rotating +- name: cross + refreshRate: 100 + states: + - "╔" + - "╩" + - "╗" + - "╣" + - "╝" + - "╩" + - "╚" + - "╠" \ No newline at end of file From b3a7f53ce645915b3ac9768b67d238db987d9732 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 15:38:17 +0100 Subject: [PATCH 4/9] moved builtin style to yaml --- .../ActivityIndicator+CommandArgument.swift | 8 +--- Sources/ActivityIndicator.swift | 38 --------------- custom-styles.yml | 46 +++++++++++++++---- 3 files changed, 39 insertions(+), 53 deletions(-) diff --git a/Sources/ActivityIndicator+CommandArgument.swift b/Sources/ActivityIndicator+CommandArgument.swift index 8dce245..d7ef55e 100644 --- a/Sources/ActivityIndicator+CommandArgument.swift +++ b/Sources/ActivityIndicator+CommandArgument.swift @@ -3,23 +3,19 @@ import TaggedTime enum ActivityIndicatorStyle: ExpressibleByArgument { case dots - case kitt - case snake case spinner case custom(String) init?(argument: String) { switch argument { case "dots": self = .dots - case "kitt": self = .kitt - case "snake": self = .snake case "spinner": self = .spinner default: self = .custom(argument) } } static var allCases: [String] { - ["dots", "kitt", "snake", "spinner"] + ["dots", "spinner"] } } @@ -39,8 +35,6 @@ extension ActivityIndicator { // Fallback to built-in styles switch style { case .dots: return .dots - case .kitt: return .kitt - case .snake: return .snake case .spinner: return .spinner case .custom(_): return .spinner // Default to spinner if custom style fails to load } diff --git a/Sources/ActivityIndicator.swift b/Sources/ActivityIndicator.swift index 7534758..c42bfe9 100644 --- a/Sources/ActivityIndicator.swift +++ b/Sources/ActivityIndicator.swift @@ -39,44 +39,6 @@ extension ActivityIndicator { return ActivityIndicator(configuration: configuration) }() - static let kitt: ActivityIndicator = { - let configuration = Configuration( - refreshRate: 125, - states: [ - "▰▱▱▱▱", - "▰▰▱▱▱", - "▰▰▰▱▱", - "▱▰▰▰▱", - "▱▱▰▰▰", - "▱▱▱▰▰", - "▱▱▱▱▰", - "▱▱▱▰▰", - "▱▱▰▰▰", - "▱▰▰▰▱", - "▰▰▰▱▱", - "▰▰▱▱▱", - ] - ) - return ActivityIndicator(configuration: configuration) - }() - - static let snake: ActivityIndicator = { - let configuration = Configuration( - refreshRate: 125, - states: [ - "▰▱▱▱▱", - "▰▰▱▱▱", - "▰▰▰▱▱", - "▱▰▰▰▱", - "▱▱▰▰▰", - "▱▱▱▰▰", - "▱▱▱▱▰", - "▱▱▱▱▱", - ] - ) - return ActivityIndicator(configuration: configuration) - }() - static let spinner: ActivityIndicator = { let configuration = Configuration( refreshRate: 125, diff --git a/custom-styles.yml b/custom-styles.yml index a4f380f..59cc742 100644 --- a/custom-styles.yml +++ b/custom-styles.yml @@ -1,6 +1,36 @@ +# Knightrider +- name: kitt + refreshRate: 125 + states: + - "▰▱▱▱▱" + - "▰▰▱▱▱" + - "▰▰▰▱▱" + - "▱▰▰▰▱" + - "▱▱▰▰▰" + - "▱▱▱▰▰" + - "▱▱▱▱▰" + - "▱▱▱▰▰" + - "▱▱▰▰▰" + - "▱▰▰▰▱" + - "▰▰▰▱▱" + - "▰▰▱▱▱" + +# Snake +- name: snake + refreshRate: 125 + states: + - "▰▱▱▱▱" + - "▰▰▱▱▱" + - "▰▰▰▱▱" + - "▱▰▰▰▱" + - "▱▱▰▰▰" + - "▱▱▱▰▰" + - "▱▱▱▱▰" + - "▱▱▱▱▱" + # Built-in like animation with hearts - name: hearts - refreshRate: 125 # milliseconds between states + refreshRate: 125 states: - 💗 - 💓 @@ -11,12 +41,12 @@ - name: arrows refreshRate: 150 states: - - "→" - - "⇒" - - "âŸč" - - "⇒" + - "→ " + - "⇒ " + - "âŸč " + - "⇒ " -# Matrix-style falling characters +# Blocks progressing - name: blocks refreshRate: 100 states: @@ -33,7 +63,7 @@ - "███" - "░ " -# Contruct rotating +# Rotating cross - name: cross refreshRate: 100 states: @@ -44,4 +74,4 @@ - "╝" - "╩" - "╚" - - "╠" \ No newline at end of file + - "╠" From c015e1f0c6dd8ac67042e80b55a341f0bed06814 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 15:51:57 +0100 Subject: [PATCH 5/9] checkmark and prompt by styles config --- Sources/ActivityConfiguration.swift | 19 +++++++++++++++++-- .../ActivityIndicator+CommandArgument.swift | 13 ++++++++----- Sources/ProgressLine.swift | 6 +++++- Sources/ProgressLineController.swift | 6 +++++- Sources/ProgressLineFormatter.swift | 8 +++++++- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/Sources/ActivityConfiguration.swift b/Sources/ActivityConfiguration.swift index 6d434bc..d9ac19c 100644 --- a/Sources/ActivityConfiguration.swift +++ b/Sources/ActivityConfiguration.swift @@ -6,9 +6,20 @@ struct ActivityStyleConfig: Codable { let name: String let refreshRate: UInt64 let states: [String] + let checkmark: String? + let prompt: String? } struct ActivityConfiguration { + struct StyleConfig { + let indicator: ActivityIndicator + let checkmark: String + let prompt: String + + static let defaultCheckmark = "✓" + static let defaultPrompt = ">" + } + static func loadConfiguration(from path: String) throws -> [ActivityStyleConfig] { let url = URL(fileURLWithPath: path) let yamlString = try String(contentsOf: url, encoding: .utf8) @@ -16,11 +27,15 @@ struct ActivityConfiguration { return try decoder.decode([ActivityStyleConfig].self, from: yamlString) } - static func createActivityIndicator(from config: ActivityStyleConfig) -> ActivityIndicator { + static func createStyleConfig(from config: ActivityStyleConfig) -> StyleConfig { let configuration = ActivityIndicator.Configuration( refreshRate: Milliseconds(config.refreshRate), states: config.states ) - return ActivityIndicator(configuration: configuration) + return StyleConfig( + indicator: ActivityIndicator(configuration: configuration), + checkmark: config.checkmark ?? StyleConfig.defaultCheckmark, + prompt: config.prompt ?? StyleConfig.defaultPrompt + ) } } \ No newline at end of file diff --git a/Sources/ActivityIndicator+CommandArgument.swift b/Sources/ActivityIndicator+CommandArgument.swift index d7ef55e..bafdbbc 100644 --- a/Sources/ActivityIndicator+CommandArgument.swift +++ b/Sources/ActivityIndicator+CommandArgument.swift @@ -20,12 +20,15 @@ enum ActivityIndicatorStyle: ExpressibleByArgument { } extension ActivityIndicator { - static func make(style: ActivityIndicatorStyle, configPath: String?) -> ActivityIndicator { + static func make(style: ActivityIndicatorStyle, configPath: String?) -> (indicator: ActivityIndicator, checkmark: String, prompt: String) { + let defaultConfig = (indicator: ActivityIndicator.spinner, checkmark: ActivityConfiguration.StyleConfig.defaultCheckmark, prompt: ActivityConfiguration.StyleConfig.defaultPrompt) + if case let .custom(styleName) = style, let configPath = configPath { do { let configs = try ActivityConfiguration.loadConfiguration(from: configPath) if let matchingConfig = configs.first(where: { $0.name == styleName }) { - return ActivityConfiguration.createActivityIndicator(from: matchingConfig) + let styleConfig = ActivityConfiguration.createStyleConfig(from: matchingConfig) + return (indicator: styleConfig.indicator, checkmark: styleConfig.checkmark, prompt: styleConfig.prompt) } } catch { print("\(ANSI.yellow)[!] progressline: Failed to load custom style '\(styleName)' from config: \(error)\(ANSI.reset)") @@ -34,9 +37,9 @@ extension ActivityIndicator { // Fallback to built-in styles switch style { - case .dots: return .dots - case .spinner: return .spinner - case .custom(_): return .spinner // Default to spinner if custom style fails to load + case .dots: return defaultConfig + case .spinner: return defaultConfig + case .custom(_): return defaultConfig } } } \ No newline at end of file diff --git a/Sources/ProgressLine.swift b/Sources/ProgressLine.swift index db2ec78..f3b0bdd 100644 --- a/Sources/ProgressLine.swift +++ b/Sources/ProgressLine.swift @@ -48,7 +48,9 @@ struct ProgressLine: AsyncParsableCommand { let logger = AboveProgressLineLogger(printers: printers) #if DEBUG - let activityIndicator: ActivityIndicator = testMode ? .disabled() : .make(style: activityIndicatorStyle, configPath: configPath) + let activityIndicator: (indicator: ActivityIndicator, checkmark: String, prompt: String) = + testMode ? (ActivityIndicator.disabled(), "✓", ">") : + ActivityIndicator.make(style: activityIndicatorStyle, configPath: configPath) #else let testMode = false let activityIndicator: ActivityIndicator = .make(style: activityIndicatorStyle, configPath: configPath) @@ -58,6 +60,8 @@ struct ProgressLine: AsyncParsableCommand { printers: printers, logger: logger, activityIndicator: activityIndicator, + checkmark: activityIndicator.checkmark, + prompt: activityIndicator.prompt, mockActivityAndDuration: testMode ) let originalLogController = if let originalLogPath { diff --git a/Sources/ProgressLineController.swift b/Sources/ProgressLineController.swift index 53cb43c..897d7ac 100644 --- a/Sources/ProgressLineController.swift +++ b/Sources/ProgressLineController.swift @@ -39,6 +39,8 @@ final actor ProgressLineController { printers: PrintersHolder, logger: AboveProgressLineLogger, activityIndicator: ActivityIndicator, + checkmark: String, + prompt: String, mockActivityAndDuration: Bool = false ) async -> Self { let progressTracker = ProgressTracker.start() @@ -46,7 +48,9 @@ final actor ProgressLineController { let progressLineFormatter = ProgressLineFormatter( activityIndicator: activityIndicator, windowSizeObserver: windowSizeObserver, - mockActivityAndDuration: mockActivityAndDuration + mockActivityAndDuration: mockActivityAndDuration, + checkmark: checkmark, + prompt: prompt ) let controller = Self( diff --git a/Sources/ProgressLineFormatter.swift b/Sources/ProgressLineFormatter.swift index 113f0f3..0040173 100644 --- a/Sources/ProgressLineFormatter.swift +++ b/Sources/ProgressLineFormatter.swift @@ -21,15 +21,21 @@ final class ProgressLineFormatter: Sendable { private let activityIndicator: ActivityIndicator private let windowSizeObserver: WindowSizeObserver? private let mockActivityAndDuration: Bool + private let checkmark: String + private let prompt: String init( activityIndicator: ActivityIndicator, windowSizeObserver: WindowSizeObserver?, - mockActivityAndDuration: Bool + mockActivityAndDuration: Bool, + checkmark: String, + prompt: String ) { self.activityIndicator = activityIndicator self.windowSizeObserver = windowSizeObserver self.mockActivityAndDuration = mockActivityAndDuration + self.checkmark = checkmark + self.prompt = prompt } func inProgress(progress: Progress) -> String { From 385f5602d2bba2d4f8c8275d043ab20f10329247 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 16:01:49 +0100 Subject: [PATCH 6/9] checkmark and prompt example --- custom-styles.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom-styles.yml b/custom-styles.yml index 59cc742..8e375f1 100644 --- a/custom-styles.yml +++ b/custom-styles.yml @@ -1,6 +1,8 @@ # Knightrider -- name: kitt - refreshRate: 125 +- name: kitt # Custom style name + checkmark: "✔" # Custom checkmark + prompt: "➀" # Custom prompt + refreshRate: 125 # Custom refresh in miliseconds states: - "▰▱▱▱▱" - "▰▰▱▱▱" From 397e42fe0af14552875f730785936b3285f41de0 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 16:04:27 +0100 Subject: [PATCH 7/9] tuple fix --- Sources/ProgressLine.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/ProgressLine.swift b/Sources/ProgressLine.swift index f3b0bdd..450984c 100644 --- a/Sources/ProgressLine.swift +++ b/Sources/ProgressLine.swift @@ -48,7 +48,7 @@ struct ProgressLine: AsyncParsableCommand { let logger = AboveProgressLineLogger(printers: printers) #if DEBUG - let activityIndicator: (indicator: ActivityIndicator, checkmark: String, prompt: String) = + let (indicator, checkmark, prompt) = testMode ? testMode ? (ActivityIndicator.disabled(), "✓", ">") : ActivityIndicator.make(style: activityIndicatorStyle, configPath: configPath) #else From 2b951b0deda55f6602537f56a76cd9665b90f816 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 16:09:43 +0100 Subject: [PATCH 8/9] forgot rename --- Sources/ProgressLine.swift | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Sources/ProgressLine.swift b/Sources/ProgressLine.swift index 450984c..71d60ae 100644 --- a/Sources/ProgressLine.swift +++ b/Sources/ProgressLine.swift @@ -49,26 +49,29 @@ struct ProgressLine: AsyncParsableCommand { #if DEBUG let (indicator, checkmark, prompt) = testMode ? - testMode ? (ActivityIndicator.disabled(), "✓", ">") : - ActivityIndicator.make(style: activityIndicatorStyle, configPath: configPath) + (ActivityIndicator.disabled(), "✓", ">") : + ActivityIndicator.make(style: activityIndicatorStyle, configPath: configPath) #else let testMode = false - let activityIndicator: ActivityIndicator = .make(style: activityIndicatorStyle, configPath: configPath) + let (indicator, checkmark, prompt) = ActivityIndicator.make(style: activityIndicatorStyle, configPath: configPath) #endif + let progressLineController = await ProgressLineController.buildAndStart( textMode: staticText.map { .staticText($0) } ?? .stdin, printers: printers, logger: logger, - activityIndicator: activityIndicator, - checkmark: activityIndicator.checkmark, - prompt: activityIndicator.prompt, + activityIndicator: indicator, + checkmark: checkmark, + prompt: prompt, mockActivityAndDuration: testMode ) + let originalLogController = if let originalLogPath { await OriginalLogController(logger: logger, path: originalLogPath) } else { OriginalLogController?.none } + let matchesController = await MatchesController(logger: logger, regexps: matchesToLog) let logAllController = shouldLogAll ? LogAllController(logger: logger) : nil From baa6c6fbc9f2b18de01c8c01d59874e8b0cb88f8 Mon Sep 17 00:00:00 2001 From: WatskeBart Date: Fri, 10 Jan 2025 16:27:14 +0100 Subject: [PATCH 9/9] removed Symbol --- Sources/ActivityIndicator+CommandArgument.swift | 3 ++- Sources/ProgressLineFormatter.swift | 8 +++++--- custom-styles.yml | 12 +++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Sources/ActivityIndicator+CommandArgument.swift b/Sources/ActivityIndicator+CommandArgument.swift index bafdbbc..6632966 100644 --- a/Sources/ActivityIndicator+CommandArgument.swift +++ b/Sources/ActivityIndicator+CommandArgument.swift @@ -22,7 +22,8 @@ enum ActivityIndicatorStyle: ExpressibleByArgument { extension ActivityIndicator { static func make(style: ActivityIndicatorStyle, configPath: String?) -> (indicator: ActivityIndicator, checkmark: String, prompt: String) { let defaultConfig = (indicator: ActivityIndicator.spinner, checkmark: ActivityConfiguration.StyleConfig.defaultCheckmark, prompt: ActivityConfiguration.StyleConfig.defaultPrompt) - + // Debug logging for configuration loading + print("Style: \(style), Config Path: \(configPath ?? "nil")") if case let .custom(styleName) = style, let configPath = configPath { do { let configs = try ActivityConfiguration.loadConfiguration(from: configPath) diff --git a/Sources/ProgressLineFormatter.swift b/Sources/ProgressLineFormatter.swift index 0040173..1802483 100644 --- a/Sources/ProgressLineFormatter.swift +++ b/Sources/ProgressLineFormatter.swift @@ -36,6 +36,8 @@ final class ProgressLineFormatter: Sendable { self.mockActivityAndDuration = mockActivityAndDuration self.checkmark = checkmark self.prompt = prompt + // Debug logging for symbols + print("Initialized ProgressLineFormatter with checkmark: '\(checkmark)' and prompt: '\(prompt)'") } func inProgress(progress: Progress) -> String { @@ -44,7 +46,7 @@ final class ProgressLineFormatter: Sendable { let styledActivityIndicator = ANSI.blue + activityIndicator + ANSI.reset let styledDuration = ANSI.bold + formattedDuration + ANSI.reset - let styledPrompt = ANSI.blue + Symbol.prompt + ANSI.reset + let styledPrompt = ANSI.blue + prompt + ANSI.reset return buildResultString( styledActivityIndicator: styledActivityIndicator, @@ -57,9 +59,9 @@ final class ProgressLineFormatter: Sendable { func finished(progress: Progress?) -> String { let formattedDuration = mockActivityAndDuration ? "" : progress.map { formatDuration(from: $0.duration) } - let styledActivityIndicator = ANSI.green + Symbol.checkmark + ANSI.reset + let styledActivityIndicator = ANSI.green + checkmark + ANSI.reset let styledDuration = formattedDuration.map { ANSI.bold + $0 + ANSI.reset } - let styledPrompt = ANSI.green + Symbol.prompt + ANSI.reset + let styledPrompt = ANSI.green + prompt + ANSI.reset return buildResultString( styledActivityIndicator: styledActivityIndicator, diff --git a/custom-styles.yml b/custom-styles.yml index 8e375f1..87bba89 100644 --- a/custom-styles.yml +++ b/custom-styles.yml @@ -1,7 +1,7 @@ # Knightrider - name: kitt # Custom style name checkmark: "✔" # Custom checkmark - prompt: "➀" # Custom prompt + prompt: ">" # Custom prompt refreshRate: 125 # Custom refresh in miliseconds states: - "▰▱▱▱▱" @@ -19,6 +19,8 @@ # Snake - name: snake + checkmark: "✔" + prompt: ">" refreshRate: 125 states: - "▰▱▱▱▱" @@ -32,6 +34,8 @@ # Built-in like animation with hearts - name: hearts + checkmark: "❀" + prompt: "💘" refreshRate: 125 states: - 💗 @@ -41,6 +45,8 @@ # Arrow animation with longer refresh rate - name: arrows + checkmark: "✔" + prompt: ">" refreshRate: 150 states: - "→ " @@ -50,6 +56,8 @@ # Blocks progressing - name: blocks + checkmark: "✔" + prompt: ">" refreshRate: 100 states: - "▒ " @@ -67,6 +75,8 @@ # Rotating cross - name: cross + checkmark: "✔" + prompt: ">" refreshRate: 100 states: - "╔"