Mun*_*ndi 4 macos cocoa newline objective-c swift
我在Swift中构建了一个OS X命令行工具(Objective-C中的同样问题),用于下载某些文件.我正在尝试使用下载进度更新命令行.不幸的是,我无法阻止print语句跳转到下一行.
根据我的研究,回车\r应该跳到同一行的开头(同时\n插入一条新线).
所有测试都在OS X终端应用程序中执行,而不是在Xcode控制台上执行.
let logString = String(format: "%2i%% %.2fM \r", percentage, megaBytes)
print(logString)
Run Code Online (Sandbox Code Playgroud)
仍然,显示器插入一个新行.怎么预防这个?
注意:这在Xcode的调试器窗口中不起作用,因为它不是真正的终端仿真器,并且不完全支持转义序列.因此,要进行测试,您必须编译它,然后在终端窗口中手动运行它.
\r应该可以在大多数终端中移动到当前行的开头,但是您还应该看看VT100终端控制转义序列.它们通过\u{1B}在Swift中发送转义字符然后执行命令来工作.(警告:他们制作一些非常难看的字符串定义)
您可能需要的是\u{1B}[K清除当前光标位置到结尾的线条.如果你不这样做,你的进度输出长度不一样,你会得到以前的print语句遗留下来的工件.
其他一些有用的是:
\u{1B}[\(y);\(x)H 注意:x和y是Int插入有字符串插值秒.\u{1B}7\u{1B}8\u{1B}[2J您还可以执行有趣的操作,例如设置文本前景色和背景色.
如果由于某种原因你无法开始\r工作,你可以通过在打印之前保存光标状态/位置logString然后在之后恢复它来解决它:
let logString = String(format: "\u{1B}7%2i%% %.2fM \u{1B}8", percentage, megaBytes)
print(logString)
Run Code Online (Sandbox Code Playgroud)
或者在打印之前移动到预定义的(x,y)位置:
let x = 0
let y = 1 // Rows typically start at 1 not 0, but it depends on the terminal and shell
let logString = String(format: "\u{1B}[\(y);\(x)H%2i%% %.2fM ", percentage, megaBytes)
print(logString)
Run Code Online (Sandbox Code Playgroud)
这是一个示例,假设一些异步任务正在通过传递 Progress 类型的回调发生。
// Print an empty string first otherwise whichever line is above the printed out progress will be removed
print("")
let someProgressCallback: ExampleAsyncCallbackType = { progress in
let percentage = Int(progress.fractionCompleted * 100)
print("\u{1B}[1A\u{1B}[KDownloaded: \(percentage)%")
}
Run Code Online (Sandbox Code Playgroud)
关键部分是\u{1B}[1A\u{1B}[K然后任何你想打印到下面的屏幕上。
您的示例仅适用于实际命令行,而不适用于调试器控制台。而且您还需要为每次迭代刷新标准输出,如下所示:
var logString = String(format: "%2i%% %.2fM \r", 10, 5)
print(logString)
fflush(__stdoutp)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1761 次 |
| 最近记录: |