使用 Swift 命令行工具的颜色输出
Color ouput with Swift command line tool
我正在使用 Swift 编写命令行工具,但在 shell 中显示颜色时遇到问题。我正在使用以下代码:
println("3[31;32mhey3[39;39m")
甚至
NSFileHandle.fileHandleWithStandardOutput().writeData("3[31;32mhey3[39;39m".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
当我在 php 中使用简单的 echo 时它有效(文本显示为绿色)但是它在 Swift 命令行工具中不起作用的原因是什么?
谢谢!
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")
希望对您有所帮助。
基于@cyt answer,我用这些颜色编写了一个简单的枚举,还重载了 +
运算符,因此您可以使用该枚举进行打印。
都是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())
}
如果您不介意将它用作框架,您可以使用 Rainbow。
import Rainbow
print("Red text".red)
print("Yellow background".onYellow)
print("Light green text on white background".lightGreen.onWhite)
结合@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)"
扩展 we can incorporate the functionality of Rainbow, as referenced in ,无需使用简单的 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)
}
}
这是我的解决方案:
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)
我正在使用 Swift 编写命令行工具,但在 shell 中显示颜色时遇到问题。我正在使用以下代码:
println("3[31;32mhey3[39;39m")
甚至
NSFileHandle.fileHandleWithStandardOutput().writeData("3[31;32mhey3[39;39m".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
当我在 php 中使用简单的 echo 时它有效(文本显示为绿色)但是它在 Swift 命令行工具中不起作用的原因是什么?
谢谢!
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")
希望对您有所帮助。
基于@cyt answer,我用这些颜色编写了一个简单的枚举,还重载了 +
运算符,因此您可以使用该枚举进行打印。
都是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())
}
如果您不介意将它用作框架,您可以使用 Rainbow。
import Rainbow
print("Red text".red)
print("Yellow background".onYellow)
print("Light green text on white background".lightGreen.onWhite)
结合@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)"
扩展 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)
}
}
这是我的解决方案:
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)