web-dev-qa-db-ja.com

Swiftコマンドラインツールを使用したカラー出力

Swiftを使用してコマンドラインツールを作成していますが、シェルで色を表示できません。次のコードを使用しています。

println("\033[31;32mhey\033[39;39m")

あるいは

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

PHPで単純なエコーを使用すると機能します(テキストは緑色で表示されます)が、Swiftコマンドラインツールで機能しない理由はありますか?

ありがとう!

18
Romain Pouclet

Swiftには、Unicodeサポートが組み込まれています。これにより、バックスラッシュの使用が無効になります。 "\ u {}"構文のカラーコードを使用するためです。これは、ターミナルで完全に機能するprintlnコードです。

// \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")

それが役に立てば幸い。

36
cyt

@ cytの回答に基づいて、これらの色で単純な列挙型を作成し、+演算子もオーバーロードしたので、その列挙型を使用して印刷できます。

それはすべて Githubにアップ ですが、実際にはそれほど単純です。

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())
}
27
Diego Freniche

レインボーをフレームワークとして使用することを気にしない場合は、レインボーを使用できます。

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

https://github.com/onevcat/Rainbow

10
UnchartedWorks

@Diegoの回答のいくつかを組み合わせると、Swiftの新しいDefaultStringInterpolation構造を使用して、この装飾を文字列リテラルに拡張できます–

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)"
3

拡張 Diego Frenicheの回答ncharted Works's Answer で参照されているように、単純なStringを使用してフレームワーク自体をインポートする必要なく、Rainbowの機能を組み込むことができます。拡張:

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)
    }

}
2
NoodleOfDeath