Color ouput with Swift command line tool

后端 未结 6 1829
萌比男神i
萌比男神i 2021-02-01 05:21

I\'m writing a command line tool with Swift and I\'m having trouble displaying colors in my shell. I\'m using the following code:

println(\"\\033[31;32mhey\\033         


        
相关标签:
6条回答
  • 2021-02-01 05:48

    Based on @cyt answer, I've written a simple enum with these colors and also overloaded + operator so you can print using that enum.

    It's all up on Github, but it's really that simple:

    enum ANSIColors: String {
        case black = "\u{001B}[0;30m"
        case red = "\u{001B}[0;31m"
        case green = "\u{001B}[0;32m"
        case yellow = "\u{001B}[0;33m"
        case blue = "\u{001B}[0;34m"
        case magenta = "\u{001B}[0;35m"
        case cyan = "\u{001B}[0;36m"
        case white = "\u{001B}[0;37m"
    
        func name() -> String {
            switch self {
            case .black: return "Black"
            case .red: return "Red"
            case .green: return "Green"
            case .yellow: return "Yellow"
            case .blue: return "Blue"
            case .magenta: return "Magenta"
            case .cyan: return "Cyan"
            case .white: return "White"
            }
        }
    
        static func all() -> [ANSIColors] {
            return [.black, .red, .green, .yellow, .blue, .magenta, .cyan, .white]
        }
    }
    
    func + (let left: ANSIColors, let right: String) -> String {
        return left.rawValue + right
    }
    
    // END
    
    
    // Demo:
    
    for c in ANSIColors.all() {
        println(c + "This is printed in " + c.name())
    }
    
    0 讨论(0)
  • 2021-02-01 05:49

    Combining some of @Diego's answer, you can use Swift's new DefaultStringInterpolation structure to extend this decoration into your string literals–

    enum ASCIIColor: String {
        case black = "\u{001B}[0;30m"
        case red = "\u{001B}[0;31m"
        case green = "\u{001B}[0;32m"
        case yellow = "\u{001B}[0;33m"
        case blue = "\u{001B}[0;34m"
        case magenta = "\u{001B}[0;35m"
        case cyan = "\u{001B}[0;36m"
        case white = "\u{001B}[0;37m"
        case `default` = "\u{001B}[0;0m"
    }
    
    extension DefaultStringInterpolation {
        mutating func appendInterpolation<T: CustomStringConvertible>(_ value: T, color: ASCIIColor) {
            appendInterpolation("\(color.rawValue)\(value)\(ASCIIColor.default.rawValue)")
        }
    }
    // USAGE:
    // "\("only this string will be green!", color: .green)"
    
    0 讨论(0)
  • 2021-02-01 05:52

    You can use Rainbow if you don't mind using it as a framework.

    import Rainbow
    print("Red text".red)
    print("Yellow background".onYellow)
    print("Light green text on white background".lightGreen.onWhite)
    

    https://github.com/onevcat/Rainbow

    0 讨论(0)
  • 2021-02-01 05:56

    Swift has built in unicode support. This invalidates using of back slash. So that I use color codes with "\u{}" syntax. Here is a println code which works perfectly on terminal.

    // \u{001B}[\(attribute code like bold, dim, normal);\(color code)m
    
    // Color codes
    // black   30
    // red     31
    // green   32
    // yellow  33
    // blue    34
    // magenta 35
    // cyan    36
    // white   37
    
    println("\u{001B}[0;33myellow")
    

    Hope it helps.

    0 讨论(0)
  • 2021-02-01 06:01

    Expanding upon Diego Freniche's answer we can incorporate the functionality of Rainbow, as referenced in Uncharted Works's Answer, without needing to import the framework itself using a simple String extension:

    enum ANSIColor: String {
    
        typealias This = ANSIColor
    
        case black = "\u{001B}[0;30m"
        case red = "\u{001B}[0;31m"
        case green = "\u{001B}[0;32m"
        case yellow = "\u{001B}[0;33m"
        case blue = "\u{001B}[0;34m"
        case magenta = "\u{001B}[0;35m"
        case cyan = "\u{001B}[0;36m"
        case white = "\u{001B}[0;37m"
        case `default` = "\u{001B}[0;0m"
    
        static var values: [This] {
            return [.black, .red, .green, .yellow, .blue, .magenta, .cyan, .white, .default]
        }
    
        static var names: [This: String] = {
            return [
                .black: "black",
                .red: "red",
                .green: "green",
                .yellow: "yellow",
                .blue: "blue",
                .magenta: "magenta",
                .cyan: "cyan",
                .white: "white",
                .default: "default",
            ]
        }
    
        var name: String {
            return This.names[self] ?? "unknown"
        }
    
        static func + (lhs: This, rhs: String) -> String {
            return lhs.rawValue + rhs
        }
    
        static func + (lhs: String, rhs: This) -> String {
            return lhs + rhs.rawValue
        }
    
    }
    
    extension String {
    
        func colored(_ color: ANSIColor) -> String {
            return color + self + ANSIColor.default
        }
    
        var black: String {
            return colored(.black)
        }
    
        var red: String {
            return colored(.red)
        }
    
        var green: String {
            return colored(.green)
        }
    
        var yellow: String {
            return colored(.yellow)
        }
    
        var blue: String {
            return colored(.blue)
        }
    
        var magenta: String {
            return colored(.magenta)
        }
    
        var cyan: String {
            return colored(.cyan)
        }
    
        var white: String {
            return colored(.white)
        }
    
    }
    
    0 讨论(0)
  • 2021-02-01 06:01

    Here is my solution:

    struct Colors {
        static let reset = "\u{001B}[0;0m"
        static let black = "\u{001B}[0;30m"
        static let red = "\u{001B}[0;31m"
        static let green = "\u{001B}[0;32m"
        static let yellow = "\u{001B}[0;33m"
        static let blue = "\u{001B}[0;34m"
        static let magenta = "\u{001B}[0;35m"
        static let cyan = "\u{001B}[0;36m"
        static let white = "\u{001B}[0;37m"
    }
    

    Demo

    print(Colors.yellow + "Please Enter the Output Directory Name:" + Colors.reset)
    

    or

    print(Colors.yellow + "Please " + Colors.blue + "Enter " + Colors.magenta + "the Output Directory Name:" + Colors.reset)
    
    0 讨论(0)
提交回复
热议问题