Swift 中的命令行应用( 二 )


如果你在 Linux 系统上,每一个都很好 。事实上,我是从 TheCoderMerlin 的这个项目开始的,它就是这样做的 。但这是我从 Mac 上的编译器收到的令人讨厌的消息:

Swift 中的命令行应用

文章插图
 
好粗鲁 。事实证明,Darwin 模块引入了它自己的 ncurses 版本,该版本包含在 MacOS 开发人员 SDK 中!这意味着头文件已经被导入,我们正在尝试重新定义之前声明的东西 。此外,MacOS SDK 中的 ncurses 版本在 5.8 版上已经过时了……据我所知,这大约是 2011 年 。为什么?!我花了几个小时在 StackOverflow 上寻找修复程序,就在我准备在我的电脑上邮寄时,我遇到了一个解决方案 。简而言之,您可以在运行 swift build 时传递 -Xcc -D__NCURSES_H ,这会告诉编译器忽略所有 ncurses 头文件 。这样做的问题是,同样的问题也出现在 brew 安装的 ncurses 版本中......并且要解决这个问题,您必须在本地复制所有 ncurses 标头并用其他东西替换 __NCURSES_H 的实例 。
为了使这个冗长的故事简短,我终于得到了在 Mac 和 Linux 上编译和工作的东西,但是所有的头文件混合都会让维护变得非常痛苦,而且仍然有一个交易破坏者 。任何对使用 wrapper 包感兴趣的用户都必须在他们自己的项目中包含 -Xcc -D__NCURSES_H C 编译器标志 。这不会给开发人员带来愉快的体验……所以我存档了项目并继续前进 。安息吧 SwiftNCurses 。
终点站
从那时起,我编写了一个纯粹基于 ANSI 的 Swift 包,名为 Terminus,现在我想与您分享 。
这是演示如何使用样式和颜色写入终端的示例代码:
import Terminuslet Terminal = Terminal.sharedterminal.write("I am bold and underlined.n", attributes: [.bold, .underline])let greenColor = Color(r:0, g:255, b:0)terminal.write("Grass is green.n", attributes: [.color(greenColor)])let palette = XTermPalette()let blueOneYellow = ColorPair(foreground: palette.Blue1, background: palette.Yellow1)terminal.write("Blue on yellow", attributes: [.colorPair(blueOneYellow)])
Swift 中的命令行应用

文章插图
 
请注意,您可以为文本添加任意数量的样式和/或颜色 。可以使用 RGB 或使用来自内置调色板之一的命名颜色来指定颜色,例如我在此处使用的 XTerm 调色板 。该文档为每个调色板提供了一个可视化图表 。
Swift 中的命令行应用

文章插图
 
Terminus 还支持 AttributedStrings 。
import Foundationimport Terminuslet terminal = Terminal.sharedvar attributedString = AttributedString("Hello, bold, underlined, world.")if let boldRange = attributedString.range(of: "bold") {attributedString[boldRange].terminalTextAttributes = [.bold]if let underlinedRange = attributedString.range(of: "underlined") {attributedString[underlinedRange].terminalTextAttributes = [.underline]terminal.write(attributedString: attributedString)
Swift 中的命令行应用

文章插图
 
现在来看一些更有趣的东西 。这是制作菜单的一些代码 。
import Foundationimport Terminuslet terminal = Terminal.sharedterminal.clearScreen()terminal.cursor.moveToHome()let palette = XTermPalette()let itemColor = palette.Aquamarine2let selectionColor = palette.Green5let menuItems = ["Life", "Death", "Taxes"]let menu = Menu(items: menuItems, maxColumns: 1, scrollDirection: .vertical, itemAttributes: [.color(itemColor)], selectionAttributes: [.reverse, .color(selectionColor)])let selection = menu.getSelection()
Swift 中的命令行应用

文章插图
 
最后但并非最不重要的......使用采用文本突出显示的行编辑器 。
import Terminuslet terminal = Terminal.sharedlet lineEditor = LineEditor()lineEditor.bufferHandler = {var shouldWriteBuffer = falseif let greenRange = lineEditor.buffer.range(of: "green") {lineEditor.buffer[greenRange].terminalTextAttributes = [.color(Color(r: 0, g: 255, b: 0))]shouldWriteBuffer = trueif let yellowRange = lineEditor.buffer.range(of: "yellow") {lineEditor.buffer[yellowRange].terminalTextAttributes = [.color(Color(r: 255, g: 255, b: 0))]shouldWriteBuffer = trueif let redRange = lineEditor.buffer.range(of: "red") {lineEditor.buffer[redRange].terminalTextAttributes = [.color(Color(r: 255, g: 0, b: 0))]shouldWriteBuffer = truereturn shouldWriteBufferlet input = lineEditor.getInput()


推荐阅读