@@ -2,78 +2,117 @@ import Foundation
2
2
3
3
/// Represents a stream that can write text with a specific set of ANSI colors
4
4
protocol ColoredStream : TextOutputStream {
5
- mutating func write( _ string: String , with: [ ANSIColor ] )
5
+ mutating func write( _ string: String , with: [ ANSIColor ] )
6
6
}
7
7
8
8
extension ColoredStream {
9
- /// Default conformance to TextOutputStream
10
- mutating func write( _ string: String ) {
11
- write ( string, with: [ ] )
12
- }
9
+ /// Default conformance to TextOutputStream
10
+ mutating func write( _ string: String ) {
11
+ write ( string, with: [ ] )
12
+ }
13
13
}
14
14
15
15
/// An output stream that prints to an underlying stream including ANSI color
16
16
/// codes.
17
17
class ColoredANSIStream < StreamTy: TextOutputStream > : ColoredStream {
18
18
19
- typealias StreamType = StreamTy
19
+ typealias StreamType = StreamTy
20
20
21
- var currentColors = [ ANSIColor] ( )
22
- var stream : StreamType
23
- let colored : Bool
21
+ var currentColors = [ ANSIColor] ( )
22
+ var stream : StreamType
23
+ let colored : Bool
24
24
25
- /// Creates a new ColoredANSIStream that prints to an underlying stream.
26
- ///
27
- /// - Parameters:
28
- /// - stream: The underlying stream
29
- /// - colored: Whether to provide any colors or to pass text through
30
- /// unmodified. Set this to false and ColoredANSIStream is
31
- /// a transparent wrapper.
32
- init ( _ stream: inout StreamType , colored: Bool = true ) {
33
- self . stream = stream
34
- self . colored = colored
35
- }
25
+ /// Creates a new ColoredANSIStream that prints to an underlying stream.
26
+ ///
27
+ /// - Parameters:
28
+ /// - stream: The underlying stream
29
+ /// - colored: Whether to provide any colors or to pass text through
30
+ /// unmodified. Set this to false and ColoredANSIStream is
31
+ /// a transparent wrapper.
32
+ init ( _ stream: inout StreamType , colored: Bool = true ) {
33
+ self . stream = stream
34
+ self . colored = colored
35
+ }
36
36
37
- /// Initializes with a stream, always colored.
38
- ///
39
- /// - Parameter stream: The underlying stream receiving writes.
40
- required init ( _ stream: inout StreamType ) {
41
- self . stream = stream
42
- self . colored = true
43
- }
37
+ /// Initializes with a stream, always colored.
38
+ ///
39
+ /// - Parameter stream: The underlying stream receiving writes.
40
+ required init ( _ stream: inout StreamType ) {
41
+ self . stream = stream
42
+ self . colored = true
43
+ }
44
44
45
- /// Adds a color to the in-progress colors.
46
- func addColor( _ color: ANSIColor ) {
47
- guard colored else { return }
48
- stream. write ( color. rawValue)
49
- currentColors. append ( color)
50
- }
45
+ /// Adds a color to the in-progress colors.
46
+ func addColor( _ color: ANSIColor ) {
47
+ guard colored else { return }
48
+ stream. write ( color. rawValue)
49
+ currentColors. append ( color)
50
+ }
51
51
52
- /// Resets this stream back to the default color.
53
- func reset( ) {
54
- if currentColors. isEmpty { return }
55
- stream. write ( ANSIColor . reset. rawValue)
56
- currentColors = [ ]
57
- }
52
+ /// Resets this stream back to the default color.
53
+ func reset( ) {
54
+ if currentColors. isEmpty { return }
55
+ stream. write ( ANSIColor . reset. rawValue)
56
+ currentColors = [ ]
57
+ }
58
58
59
- /// Sets the current ANSI color codes to the passed-in colors.
60
- func setColors( _ colors: [ ANSIColor ] ) {
61
- guard colored else { return }
62
- reset ( )
63
- for color in colors {
64
- stream. write ( color. rawValue)
65
- }
66
- currentColors = colors
59
+ /// Sets the current ANSI color codes to the passed-in colors.
60
+ func setColors( _ colors: [ ANSIColor ] ) {
61
+ guard colored else { return }
62
+ reset ( )
63
+ for color in colors {
64
+ stream. write ( color. rawValue)
67
65
}
66
+ currentColors = colors
67
+ }
68
68
69
- /// Writes the string to the output with the provided colors.
70
- ///
71
- /// - Parameters:
72
- /// - string: The string to write
73
- /// - colors: The colors used on the string
74
- func write( _ string: String , with colors: [ ANSIColor ] ) {
75
- self . setColors ( colors)
76
- stream. write ( string)
77
- self . reset ( )
69
+ /// Writes the string to the output with the provided colors.
70
+ ///
71
+ /// - Parameters:
72
+ /// - string: The string to write
73
+ /// - colors: The colors used on the string
74
+ func write( _ string: String , with colors: [ ANSIColor ] ) {
75
+ self . setColors ( colors)
76
+ stream. write ( string)
77
+ self . reset ( )
78
+ }
79
+ }
80
+
81
+ /// Represents the possible ANSI color codes.
82
+ enum ANSIColor : String {
83
+ case black = " \u{001B} [30m "
84
+ case red = " \u{001B} [31m "
85
+ case green = " \u{001B} [32m "
86
+ case yellow = " \u{001B} [33m "
87
+ case blue = " \u{001B} [34m "
88
+ case magenta = " \u{001B} [35m "
89
+ case cyan = " \u{001B} [36m "
90
+ case white = " \u{001B} [37m "
91
+ case bold = " \u{001B} [1m "
92
+ case reset = " \u{001B} [0m "
93
+
94
+ func name( ) -> String {
95
+ switch self {
96
+ case . black: return " Black "
97
+ case . red: return " Red "
98
+ case . green: return " Green "
99
+ case . yellow: return " Yellow "
100
+ case . blue: return " Blue "
101
+ case . magenta: return " Magenta "
102
+ case . cyan: return " Cyan "
103
+ case . white: return " White "
104
+ case . bold: return " Bold "
105
+ case . reset: return " Reset "
78
106
}
107
+ }
108
+
109
+ static func all( ) -> [ ANSIColor ] {
110
+ return [ . black, . red, . green,
111
+ . yellow, . blue, . magenta,
112
+ . cyan, . white, . bold, . reset]
113
+ }
114
+ }
115
+
116
+ func + ( left: ANSIColor , right: String ) -> String {
117
+ return left. rawValue + right
79
118
}
0 commit comments