Вывод цвета с помощью инструмента командной строки Swift
Я пишу инструмент командной строки со Swift, и у меня возникают проблемы с отображением цветов в моей оболочке. Я использую следующий код:
println("\033[31;32mhey\033[39;39m")
или даже
NSFileHandle.fileHandleWithStandardOutput().writeData("\033[31;32mhey\033[39;39m".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!)
Это работает, когда я использую простое эхо в php (текст отображается зеленым цветом), но есть ли причина, по которой он не работает в инструменте командной строки Swift?
Спасибо!
7 ответов
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, я написал простое перечисление с этими цветами, а также перегружен +
оператор, так что вы можете печатать, используя это перечисление.
Это все на 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())
}
Вы можете использовать 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)"
Вот мое решение:
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)
Расширяя ответ Диего Френиша, мы можем включить функциональность Rainbow, как указано в ответе Uncharted Works, без необходимости импортировать саму структуру с помощью простого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)
}
}
Используйте шрифт из ColoredConsole плюс расширение дляString
.
- Установите ColoredConsole-Bold.ttf
- В Xcode установите для вывода на консоль шрифт «Цветная консоль, полужирный».
- Добавьте это расширение в String в свой проект (на основе jjrscott ).
import Foundation
public extension String {
var consoleColor: ColoredConsoleString {
ColoredConsoleString(self)
}
}
public class ColoredConsoleString {
var string: String
public enum ColorSelectors: String {
case red = "\u{fe06}"
case green = "\u{fe07}"
case brown = "\u{fe08}"
case teal = "\u{fe09}"
case purple = "\u{fe0a}"
}
init(_ str: String) {
string = str
}
public var teal: String {
wrappedString(color: .teal, string)
}
public var purple: String {
wrappedString(color: .purple, string)
}
public var red: String {
wrappedString(color: .red, string)
}
public var green: String {
wrappedString(color: .green, string)
}
public var brown: String {
wrappedString(color: .brown, string)
}
private func wrappedString(color: ColorSelectors, _ string: String) -> String {
Array(string).map({ "\($0)\(color.rawValue)"}).joined()
}
}
- Теперь вы можете вывести на консоль строки трех разных цветов:
print("red".consoleColor.red)
print("green!".consoleColor.green)
print("purple".consoleColor.purple)
print("brown".consoleColor.brown)
print("teal".consoleColor.teal)
Работает с Xcode 14.3 и, возможно, более старыми версиями.
- Примечание.
po print("red".consoleColor.red)
на снимке экрана сообщает отладчику Xcode (lldb) вычислить и распечатать выражение. Больше оpo
здесь