Определить размер области просмотра (в символах) из приложения командной строки в Swift?

Я создаю инструмент командной строки в Swift, и мне интересно, есть ли способ определить текущую ширину области просмотра при запуске приложения, чтобы ограничить текст на экране тем, что будет соответствовать без переноса.

Я знаю, что это возможно в «настоящем» приложении командной строки, поскольку такие вещи, как pico, man, pine и т. д., отображают свои текстовые интерфейсы в зависимости от размера окна, но я не могу найти никакой информации о том, как они это делают. Это.

На самом деле вы даже можете изменить размер окна во время их работы, и они будут обновляться. Кто-нибудь знает, как это работает и можно ли добавить поддержку инструмента командной строки, написанного на Swift?


person devios1    schedule 12.12.2017    source источник
comment
В оболочке bash переменные среды LINES и COLUMNS задают размер экрана. Но они не появляются у меня при использовании ProcessInfo.processInfo.environment в инструменте командной строки Swift на Mac.   -  person rmaddy    schedule 12.12.2017
comment
Вы заботились об окне отладки xcode или просто о терминале? Как сказал @Martin R, вы можете получить ioctl, чтобы получить ширину и высоту в порядке с терминалом, но это не работает в окне отладки XCode [даже если вы измените Behavior, чтобы запустить консоль отладки на новой вкладке].   -  person rustyMagnet    schedule 26.03.2020


Ответы (1)


Код C из Получение ширины терминала в C? легко переводится на Быстрый:

import Darwin

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

(По какой-то причине это не работает в консоли отладчика Xcode, вы должны вызывать исполняемый файл в окне терминала.)

В качестве альтернативы, используя библиотеку ncurses (из Получение ширины терминала в C? ):

import Darwin.ncurses

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

Чтобы отслеживать события изменения размера окна, вы должны обрабатывать сигнал SIGWINCH, сравните Перехват сигналов в приложении командной строки Swift:

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()
person Martin R    schedule 12.12.2017
comment
Удивительно! Я бы купил тебе пива, если бы мог. Спасибо, Мартин! - person devios1; 12.12.2017
comment
@devios1: Я позвоню тебе, если когда-нибудь приеду в Канаду :) - person Martin R; 12.12.2017