Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color ouput with Swift command line tool

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[39;39m")

or even

NSFileHandle.fileHandleWithStandardOutput().writeData("\033[31;32mhey\033[39;39m".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)

It works when I use a simple echo in php (the text is displayed in green) but is there a reason it doesn't work in a Swift command line tool?

Thanks!

like image 978
Romain Pouclet Avatar asked Jan 06 '15 21:01

Romain Pouclet


3 Answers

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.

like image 139
cyt Avatar answered Oct 05 '22 18:10

cyt


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"
    case `default` = "\u{001B}[0;0m"
    
    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"
        case .default: return "Default"
        }
    }
    
    static func all() -> [ANSIColors] {
        return [.black, .red, .green, .yellow, .blue, .magenta, .cyan, .white]
    }
}

func + (left: ANSIColors, right: String) -> String {
    return left.rawValue + right
}

// END


// Demo:

for c in ANSIColors.all() {
    print(c + "This is printed in " + c.name())
}
like image 29
Diego Freniche Avatar answered Oct 05 '22 16:10

Diego Freniche


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

like image 30
webcpu Avatar answered Oct 05 '22 18:10

webcpu