从 Swift 的命令行应用程序确定视口大小(以字符为单位)?

dev*_*os1 3 command-line command-line-tool swift

我正在 Swift 中构建一个命令行工具,并且想知道是否有任何方法可以在运行应用程序时确定视口的当前宽度,以便将屏幕上的文本限制为适合不换行的内容。

我知道这在“真正的”命令行应用程序中是可能的,因为像 pico、man、pine 等都根据窗口大小呈现它们的文本界面,但我似乎找不到任何关于它们如何做的信息它。

事实上,您甚至可以在它们运行时调整窗口大小,它们会刷新。有谁知道这是如何工作的,以及是否可以为用 Swift 编写的命令行工具添加支持?

Mar*_*n R 6

来自在 C 中获取终端宽度的 C 代码很容易翻译成 Swift:

import Darwin

var w = winsize()
if ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0 {
    print("rows:", w.ws_row, "cols", w.ws_col)
}
Run Code Online (Sandbox Code Playgroud)

(出于某种原因,这在 Xcode 调试器控制台中不起作用,您必须在终端窗口中调用可执行文件。)

或者,使用 ncurses 库(来自在 C 中获取终端宽度?):

import Darwin.ncurses

initscr()
let s = "rows: \(LINES), cols: \(COLS)"
mvaddstr(1, 1, s);
refresh();
getch()
endwin()
Run Code Online (Sandbox Code Playgroud)

要跟踪窗口调整大小事件,您必须处理 SIGWINCH 信号,请在 Swift 命令行应用程序中比较Trapping 信号

import Darwin
import Dispatch

var w = winsize()
if ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0 {
    print("rows:", w.ws_row, "cols", w.ws_col)
}

let sigwinchSrc = DispatchSource.makeSignalSource(signal: SIGWINCH, queue: .main)
sigwinchSrc.setEventHandler {
    if ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0 {
        print("rows:", w.ws_row, "cols", w.ws_col)
    }
}
sigwinchSrc.resume()

dispatchMain()
Run Code Online (Sandbox Code Playgroud)