commit -m "better"
2.96K subscribers
868 photos
105 videos
3 files
2.07K links
just random thoughts
Download Telegram
#terminal

У нас тут проходил опрос на тему "какой эмулятор терминала вы используете". Я был очень удивлен, увидев, что #Alacritty там занимает предпоследнее место. Давайте я вам расскажу за эмуляторы терминала.

Исхожу я из следующих положений:

1) Благодаря встроенным в эмулятор настройкам, или используя что-то типа Karabiner Elements, keybindings можно настроить произвольным образом. Ну, то есть, можно отобразить любую комбинацию клавиш в любую последовательность ESC codes. Это упражнение можно проделать для любого известного мне эмулятора терминала. Например, я как 20 лет назад привык к keybindings от Konsole, так и использую их везде, хотя предпочтительный эмулятор терминала у меня менялся раза 4.

2) Благодаря tmux и подобным программам можно получить одинаковый(ну, почти одинаковый) user experience в любом эмуляторе терминала. Неудобство управления tmux(все вот эти C-b x) решаются с помощью пункта 1.

Какие у нас остаются различия?

1) Рендеринг шрифтов. Я имею наглость утверждать, что, если вы используете для терминала какой-то "внесистемный" рендеринг шрифтов(например, FreeType под macOS), то вы что-то делаете не так, и вам стоит поменять OS, чтобы не мучить глаза. Если вы используете системный рендеринг шрифтов в эмуляторе терминала, то вам пофиг на то, как называется программа, которая дергает системные функции.

2) Скорость отрисовки. Тут все очень просто, эту метрику можно объективно посчитать. Я инструментировал свой текстовый редактор, чтобы он умел работать с текстом в batch режиме(даем программе текстовый файл, последовательность команд, смотрим, сколько времени они выполняются). На первом месте по этой метрике получается Alacritty, остальные терминалы довольно далеко позади(iTerm, Kitty, Hyper.js, встроенный в macOS).

3) Мерцание. Это совсем не то же самое, что и 2. К сожалению, большинство терминалов написаны совсем рукожопно, поэтому они легко могут читать команды от приложения в буфер фиксированной длины, и когда буфер заканчивается, делать flush изменений прямо на экран. Это совершенно неверная модель, потому что мы легко можем сделать flush в середине отрисовки экрана приложением. По этой метрике все терминалы, за исключением одного, ведут себя довольно плохо. Единственный терминал, который я не смог уличить в мерцании, это Hyper.js(очень неплохой терминал, кстати, к сожалению, его разработку практически забросили(я знаю, что у него был релиз в первый раз за 2 года несколько дней назад, релиз "забагован" по самое не хочу)).

Короче, к чему это я? Мне кажется, что из вышеизложенного текста получается, что почти всегда сейчас нужно пользоваться Alacritty(за исключением того случая, когда для вас очень важно мерцание, тогда можно посмотреть на Hyper.js)

Раз уж начал про эмуляторы терминала, расскажу еще одну интересную вещь.

Изменение размеров окна в них сделано не посылкой in order команды программе внутри терминала, а с помощью посылки асинхронного out of order сигнала SIGWINCH(по примему которого программа должна in order спросить у эмулятора терминала новые размеры окна). Ни один известный мне эмулятор терминала не реализует этот протокол корректно - при изменении размеров окна всегда будут случаи некорректной отрисовки приложения. Правильный протокол выглядит так: когда эмулятор терминала понимает, что окно изменило размер:

1) Нужно послать SIGWINCH приложению(out of order)
2) Нужно дождаться, когда приложение пришлет запрос на определение новых размеров(in order). Послать ему ответ.
3) Вот тут тонкий момент. Так как у нас нет нормального framing и подтверждений о доставке, нужно дождаться, когда буфер в pipe становится пустым, в обе стороны. Это не всегда возможно(например, если прямо сейчас в терминале запущен cat на большой файл), поэтому эту операцию нужно делать с timeout.
4) Только в этот момент можно поменять в своих структурах данных размерности окна на новые. Если это сделать раньше, возможны глюки.

К сожалению, что эмуляторы терминала, что программы, тут предпочитают логику на sleep.
commit -m "better"
Я тут хотел накатать большой текст, но решил, что много чести. https://github.com/rust-lang/rust/issues/40174 "For those following various links to this issue, it is important to note that you can compile code using proc_macro to statically-linked musl binaries…
Мужик сказал - мужик сделал. Перешел с Alacritty на #kitty. Правда, это оказалось не так просто, как я ожидал.

#terminal

Kitty разрабатывает индус. Не, натурально, зовут его, кстати, #Ковид, и у него есть скрипт для подсчета объема его лапшеобразного кода - https://github.com/kovidgoyal/kitty/blob/master/count-lines-of-code. Код соответствующего качества.

Например, он зачем-то импортировал цельнотянутые исходники glfw в свой проект, наверное, чтобы увеличить line count. https://github.com/kovidgoyal/kitty/tree/master/glfw

Собирать статически слинкованный бинарь это решительно не помогает.

Так же мне очень нравился рендеринг шрифтов в alacritty(они там более crispy), и я долгое время искал, какую функцию рендера шрифтов MacOS нужно дернуть, чтобы получить нужный результат. Нашел, держите:

https://github.com/kovidgoyal/kitty/blob/master/kitty/core_text.m#L504

Так же #alacritty химичит с вертикальным размером шрифта - почти pixel to pixel я получил, когда обрезал шрифт на 85% исходной высоты. В коде Alacritty я с ходу этого не нашел, там слишком много вхождений литерала 85.

https://www.reddit.com/r/archlinux/comments/n9noje/alacritty_vs_kitty/ - вот, например, сравнение этих двух эмуляторов терминала.

https://wezfurlong.org/wezterm/config/files.html - пока занимался сборкой Kitty, ознакомился и с другими эмуляторами. Этот меня порадовал своим подходом к конфигурации. Конфиг - это код на lua, который должен вернуть dict. Кто-то еще помнит поисковый балансер? Гениальная же штука!

Оказывается, зря я гнал на авторов терминалов - все они понимают, что протокол терминала не позволяет нормально НЕ делать апдейты посреди процесса вывода программой своего интерфейса. Вот, пожалуйста, документ про это - https://gitlab.freedesktop.org/terminal-wg/specifications/-/merge_requests/2. Кстати, наш друг Ковид там тоже засветился. Но если понимают - то что же так криво реализуют существующую схему-то?

Кстати, Kitty мерцает существенно меньше, чем Alacritty, хотя и несколько медленнее.
https://codeberg.org/dnkl/foot/wiki/Performance #terminal

Я вот решил попробовать какой-то другой эмулятор терминала, один из самых популярных not hardware-accelerated - #foot. Автор, конечно, всячески пытается сделать вид, что он не конкурирует с alacritty:

1) Но вот в тест, где он рвет #alacritty, "срежиссирован" специально - он строчкой ранее пишет, что alacritty гораздо быстрее рендерит пустые глифы, чем заполненные, и, чтобы показать преимущество своего damage control, показывает этот damage control на полностью заполненном терминале. На терминале с небольшим числом непустых глиф даже его damage control не показал бы преимущества.

2) Чтобы его foot не совсем сильно тормозил, он сделал оптимизацию с копированием части буфера через memcpy, если он считает, что она не изменилась. И набажил - у меня при скроллинге, если предыдущие строки немного похожи на следующие, начинаются глюки отрисовки.

Ну не соревнуешься - так не соревнуйся, сделай простую, как 5 копеек, вещь, которой можно пользоваться без hardware acceleration.

———
https://github.com/dvdhrm/kmscon

#kmscon

Какой-то странный проект по замене линуксовой консоли во frame buffer. Я тоже задумался о такой штуке, но мне показалось, что гораздо проще взять киоск-style композитор на основе wlroots, и слинковать в одну программу эмулятор терминала(любой), киоск-style композитор, libinput, и все такое. Получаем бинарь с клиентом-терминалом и сервером-композитором, который умеет в консоль в fb.

———
Я хочу признаться в одной странности, которая меня никак не отпускает. Я строю prefix trie из путей к проектам в своей системе сборки Mix. Что это значит?

lib/pcre, lib/pcre/2, а не lib/pcre2. lib/tom/math, lib/tom/crypt, а не lib/tommath, lib/tomcrypt. lib/z, а не lib/zlib(а это уже что, граф?), net/wget и net/wget/2, и самое любимое - lib/curses/n, lib/curses/netbsd. Пока не сжал dev/build/autoconf, dev/build/automake, но руки чешутся.

Я хз, зачем я это делаю, но мне нравится!

———
У меня было время почитать интернеты про Vizio и ее предполагаемое нарушение GPL, понял, что зря записал ее в негодяи в прошлый раз. Вот то, что она пытается отменить суд на основе того, что иск подал не владелец кода, это не значит, что они негодяи, и у них нет возможности доказать, что они не используют GPL в своей прошивке, а это просто очень "техническая" вещь - так дешевле.
Ненавижу #cmake.

Это самая худшая система сборки ever.

* Она не умеет в кросс-компиляцию, писал об этом неоднократно #cross

* Фактически, cmake - это интерпретируемый язык с смесью синтаксиса qbasic и cobol, на которой можно как-то написать кривую и косую систему сборки, потому что язык turing complete.

Сложность скриптов на cmake ограничивается только всратостью самого языка, и ничем более.

У разработчиков QT, видимо, было очень много времени на то, чтобы разобраться с cmake, и сделать все самым ненатуральным возможным образом.

В cmake есть переменная, которая определяет список путей, по окторым искать библиотеки, заголовки, и так далее.

https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html, вот она

Ее поведение можно переопределить 10 разными способами, например

https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_PREFIX_PATH.html#variable:CMAKE_SYSTEM_PREFIX_PATH

https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_IGNORE_PATH.html#variable:CMAKE_SYSTEM_IGNORE_PATH

find_package() в cmake содержит в себе 10 настроек для этих 10 переменных, https://cmake.org/cmake/help/latest/command/find_package.html#command:find_package - искать по "NO_CMAKE_".

Каждая из которых каким-то нетривиально-всратым образом меняет семантику find_package.

Долбоебы из QT решили, что и этого им мало:

* они переопределили поведение по умолчанию, чтобы либы из QT не искались в CMAKE_PREFIX_PATH

* Они завели себе переменную QT_ADDITIONAL_PACKAGES_PREFIX_PATH, на замену CMAKE_PREFIX_PATH

* Они завели себе переменную, выключенную по умолчанию, которая возвращает поведение к "нормальному"(насколько это возможно в cmake вообще) - QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES

Я НЕНАВИЖУ, когда у программистов заканчивается работа, и они начинают маяться хуйтой.

———
Хозяйке на заметку.

Я потихоньку профилирую свой Linux, ищу, что и где плохо лежит происходит не так, как мне нравится, и починяю.

Вот, возможно, пригодится.

#foot по умолчанию запускает ncpu threads для параллельного рендеринга.

Но мы-то знаем, что дисперсия времен ответов от большого числа источников(иными словами, барьер на синхронизацию событий "мы все сделали!") штука опасная, и может быть большой. Например, потому что #scheduler в Linux - говно. Тем более, если запускать по 16 render threads. Ну и памяти под стеки они жрут прилично.

TL;DR - если убрать вообще все worker threads, и оставить только main, скорость рендеринга не меняется никак(проверяем с помощью cat на большой файл, с ansi escape codes)

Тащемта, понятно, откуда там взялся многопоток - автор foot, очевидно, испытывает комплекс перед #alacritty, и ему нужно были эти эфемерные 10% ради собственного спокойствия.

А вам я рекомендую ставить workers=0 в конфиге, работает так же, памяти жрет меньше.
🔥10👍3😁2🤔1
https://www.opennet.ru/opennews/art.shtml?num=57194

Любли читать такие тексты. Самое интересное, конечно, не что там с wayland с nvidia, а "как оно вообще бывает, и какие задачи люди решают".

У меня выкристаллизировалась такая мысль - wayland сейчас находится примерно рядом с эмуляторами терминала. #foot, #alacritty, #kitty, #wayland #terminfo

Вроде, есть какая-то спека, все договорились ее использовать, но все равно, все терминалы ее реализуют немного по разному, кто-то больше, кто-то меньше, и договориться между собой они не могут.

А сообщение программе про изменение размера терминала до сих пор идет через SIGWINCH(== dbus рядом с wayland, если вы понимаете, о чем я), а не in-band в потоке сообщений. Про проблемы этого подхода я рассказывал. https://ru.wikipedia.org/wiki/SIGWINCH

Удивительный факт - GNOME, такое ощущение, ненавидит wayland, и, была бы их воля, они бы все переделали поверх dbus. Я этого совершенно не понимаю, они стояли у его истоков.

Возможно, я тут упустил какую-то интересную часть истории, расскажите.

———
Я решил устроить фичекат в своей пакетной базе. #mix

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

Сейчас стало понятно, что пакетная база будет выглядеть очень криво, если из нее надо собирать и то, и другое.

Смотрите.

Довольно часто рядом с библиотекой лежат какие-то данные.

В случае динамической линковки очень естественно, когда .so лежит рядом с данными для этой .so. Ну, типа, если уж слинковал это либу, то и данные понадобятся.

В случае .a файлов это совершенно не так. После того, как программа слинкована, мы совершенно точно не хотим видеть рядом с данными и бинарями .a файлы.

Поэтому я разделяю пакеты не только на bin, lib(помните, рассказывал про bin, lib контексты сборки?), но еще и на aux контекст(там лежит etc/, share/, etc). Программы и библиотеки уже собираются с путями, которые указывают в этот отдельный, третий, таргет. В сборе это выглядит примерно так - https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/fontconfig/mix.sh#L14

Это будет выглядеть весьма криво в случае сборки .so файлов.

Пакетная база, которая дает красивый результат для обоих "миров" - сама по себе выглядит ужасно, там куча if, и частных случаев.

Короче, я пока решил это дело пофичекатить.
👍2
commit -m "better"
Я тут собирал #kitty под Linux, прост потому что мне не нравится, когда в репозитории есть сломанные таргеты. Так-то я использую #foot И у меня случилось всяких разрозненных мыслей по этому поводу. * Всю эту бодягу как писал индус #Ковид, так и продолжает…
#зумеры #rust #rant

Вот есть такой https://wezfurlong.org/wezterm/index.html - весь из себя ниибаца безопасный и на Rust. 11k звезд на github. Альтернатива #alacritty, потому что а почему бы и нет?

Его намертво вешает вот такая программа:

pg# cat qw.py
import sys
for i in range(0, 10000):
sys.stdout.write(chr(i))


Мораль?

Ну вот не падает программа, написанная пионером, а уходит в бесконечный цикл - кому от этого легче?
💅12😁9👍5🤮1
commit -m "better"
Я тут собирал #kitty под Linux, прост потому что мне не нравится, когда в репозитории есть сломанные таргеты. Так-то я использую #foot И у меня случилось всяких разрозненных мыслей по этому поводу. * Всю эту бодягу как писал индус #Ковид, так и продолжает…
Продолжаем развенчивать мифы про 3D ускорение терминала. #terminal

Раз уж я заполучил #rust (https://t.iss.one/itpgchannel/1605), то теперь у меня есть работающий #alacritty!

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

#alacritty:

real  0m1.039s
user 0m0.000s
sys 0m0.396s


#foot:

real  0m0.597s
user 0m0.000s
sys 0m0.362s


Что это значит?

Это значит, что, несмотря на свою похвальбу, alacritty не является самым быстрым терминалом, и что 3D ускорение в терминале - совершенно необязательно для комфортной работы.

Ссылки:
https://t.iss.one/itpgchannel/133
https://t.iss.one/itpgchannel/119
https://t.iss.one/itpgchannel/39

UPD: в коментах меня попросили побенчмаркать не бинарный треш, а что-то другое.

Вот, вывод на экран 150 мегабайт текста:

alacritty:

real  0m2.920s
user 0m0.000s
sys 0m1.456s


foot:

real  0m2.059s
user 0m0.000s
sys 0m1.534s
👍20🤡54🔥3🤯1
commit -m "better"
От автора патчей, ускорявших vte (да, да, все три терминала построены вокруг одной и той же библиотеки, #libvte, только вот у кого-то она тормозит, а у кого-то нет).

Неожиданно годный продукт, по крайней мере, не возникает позыва закрыть, и никогда больше не запускать.
https://www.phoronix.com/news/VTE-Terminals-Progress-Indicate

#ptyxis

Очередное улучшение #libvte, а #alacritty все еще быстрее, и будет быстрее.

И вот вам в копилку смешное применение #libvte - https://github.com/xyproto/orbiton

Чувак сделал текстовый редактор, а потом, когда ему понадобился gui, сказал:

"А давайте я просто запилю shell для своего текстового редактора, в виде отдельно собранного приложения на основе libvte, которое бы умело только запускать мой текстовый редактор"?

https://github.com/xyproto/orbiton/blob/main/gtk3/main.cpp

Такой html browser, только для консольных программ!
🔥9👍5🐳5🤯3
commit -m "better"
Очередное улучшение #libvte, а #alacritty все еще быстрее, и будет быстрее.
Хоба, вжух-вжух, и это поделие становится дефолтным терминалом в ubuntu!

#ptyxis

https://www.phoronix.com/news/Ubuntu-Ptyxis-Recommended

Чтобы я так жил, недоделку над #libvte - и дефолтным терминалом.

Впрочем, в последнее время очень много таких транных решений!

Как вам https://fedoraproject.org/wiki/Changes/FedoraMiracle, а?

Это fedora remix на wayland compositor, который пока есть только на бумаге (https://github.com/miracle-wm-org/miracle-wm)! А fedora на нем уже есть!
🤡8👍4🍓4
commit -m "better"
При сравнении с Alacritty производительность Ghostty была примерно на том же уровне
Все же, пока чуть медленнее:

real  0m4.624s
user 0m0.004s
sys 0m1.152s


vs

real    0m4.929s
user 0m0.004s
sys 0m1.155s


Тестировал выводом большого текстового файла.

Тест на вшивость (выводим в терминал всякий треш, ждем, что упадет) ghostty тоже вполне прошел.

#alacritty #ghostty
👍14🤡5🔥21
commit -m "better"
И я не удержался, чтобы побенчмаркать терминалы, а заодно проверить их парсер на падучесть. Напомню, что я для этого вывожу в окно терминала несколько десятков мегабайт бинарного мусора.
Как вы знаете, я иногда люблю побенчить тот или иной #terminal (#kitty #alacritty #foot #ghostty #zutty).

Делаю я это очень просто:

1) Через cat вывожу в терминал пару сотен мегабайт бинарного мусора, из /dev/random. Многие эмуляторы не проходят этот простой тест, и падают/виснут намертво, особенно я часто на этом ловил #kitty.

2) Через cat вывожу в терминал пару сотен мегабайт случайного текста, для измерения условной "скорости". Настраиваю оба терминала так, чтобы у них были одинаковые метрики по ширине и высоте текста, и одинаковый шрифт.

Вот, сегодня у нас:

#ptyxis (кстати, станет дефолтом в Ubuntu - https://www.opennet.ru/opennews/art.shtml?num=63270)

real  0m2.014s
user 0m0.002s
sys 0m0.655s
pg:home# time cat 2


И наш (уже бывший!) чемпион, #alacritty:

real  0m2.776s
user 0m0.001s
sys 0m0.799s
pg:home# time cat 2


Что?!? Да!!!

Alacritty проиграл какому-то поделию от проекта #GNOME, такие дела.
😁25👍9🆒5🔥31🐳1