【问题标题】:Color ouput with Swift command line tool使用 Swift 命令行工具进行颜色输出
【发布时间】:2015-03-04 16:00:25
【问题描述】:

我正在使用 Swift 编写命令行工具,但在我的 shell 中显示颜色时遇到问题。我正在使用以下代码:

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

甚至

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

当我在 php 中使用简单的 echo 时它可以工作(文本显示为绿色),但是它在 Swift 命令行工具中不起作用是有原因的吗?

谢谢!

【问题讨论】:

标签: swift colors command command-line-interface xterm


【解决方案1】:

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

希望对你有帮助。

【讨论】:

  • 我不适用于 iOS Swift 1.2 编程,我在输出中看不到颜色
  • Xcode 控制台不打印颜色在你没有安装 XcodeColors 插件 -> github.com/robbiehanson/XcodeColors
  • 有没有办法让部分彩色字符串和默认控制台颜色的其余字符串?
【解决方案2】:

基于@cyt 回答,我用这些颜色编写了一个简单的枚举,并且还重载了+ 运算符,以便您可以使用该枚举进行打印。

都是up on 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"
    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())
}

【讨论】:

  • "\u{001B}[0;0m" 重置为默认颜色。
  • 顺便说一句,Swift 现在提供了一个CaseIterable 协议,它为您的枚举合成一个allCases 方法,该方法返回一个包含所有案例的数组。它不适用于具有关联值的案例,尽管它与具有原始值的案例兼容。见developer.apple.com/documentation/swift/caseiterable
【解决方案3】:

如果您不介意将 Rainbow 用作框架,您可以使用它。

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

https://github.com/onevcat/Rainbow

【讨论】:

    【解决方案4】:

    结合@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)"
    

    【讨论】:

    • 感谢您也添加default
    【解决方案5】:

    Diego Freniche's answer 的基础上进行扩展,我们可以合并Rainbow 的功能,如Uncharted Works's Answer 中所引用,而无需使用简单的String 扩展来导入框架本身:

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

    【讨论】:

      【解决方案6】:

      这是我的解决方案:

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

      演示

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多