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 в своей прошивке, а это просто очень "техническая" вещь - так дешевле.
#gold #terminal #foot #perf

https://zed.dev/

CRDT - прикольно, tree sitter - тоже(хочу его интегрировать в свой редактор), GPU accelerated GUI - ну такое. Я вот раньше думал, что GPU accelerated GUI это что-то очень крутое, а потом понял, что ерунда это все. IMHO c GPU GUI нужно собрать всего 3 программы - wayland compositor(потому что он много туда-сюда гоняет пикселей), browser, terminal(уже опционально).

Знаете, какая самая дорогая для CPU задача при отрисовке html странички в браузере?

Залить страницу белым фоном!

Ладно, это не совсем так(думаю, отрисовать много текста ЧУТЬ дороже), но мне же нужен шок-контент. Это очень дорогая операция для CPU, потому что он ограничен в своей полосе по памяти, и пишет нолики(или 0xFF) один за другим. Прикиньте, выполнить цикл 3000*2000*3*60rps раз - это сколько нужно тактов? GPU это делает очень быстро - у нее более широкий доступ к памяти, и дофига тупых ядер, которые медленно(но суммарно ОЧЕНЬ быстро(можно разбить всю заливаемую область по числу ядер GPU)) выполняют цикл for (i = x1; i < x2; ++i) mem[i + y*dimx] = 0xFF;

Cобственно, это самый важный факт, который нужно знать про GPU, чтобы понимать, почему они рулят в ML и прочей подобной нечисти, но об этом в другой раз.

Отрисовка текста - это просто bit blit(https://en.wikipedia.org/wiki/Bit_blit, а кто-то помнит, что это?) нескольких текстур на GPU. (Ладно, не совсем так, в оригинальном bit blit не было смешивания с альфа-каналом).

Вообще, конечно, рендер GUI на GPU - это из пушки по воробьям, тупой аппаратный bit blit справился не хуже бы, и стоил бы при той же скорости в 100 раз дешевле. Но имеем, что имеем.

Terminal emulator Foot, например, делает эту задачу во все мои 16 потоков CPU, и работает сравнимо с alacritty(https://codeberg.org/dnkl/foot/wiki/Performance). #foot

"Крутизна" 2D GPU рендеринга несколько преувеличена. Тупой 2D render для консоли(отрисовать сетку из прямоугольничков с текстом) - 20 строк кода(если не считать setup текстур со шрифтами, и все такое). Я однажды их даже написал - https://github.com/pg83/ted/blob/3c3f54a69b806bd7eb96f4c56189ce2a7f0507c5/gl#L325 Вот, inner loop 2D GPU accelerated rendering, не хуже, чем в Alacritty. Не такой sexy, конечно, на fixed pipeline, но я люблю тупые решения. Зачем я это сделал? Мне было интересно, насколько generic я сделал widget для редактирования текста. Вот, я перенес его из консоли в OpenGL, за 100 строк кода. Пользоваться не стал, незачем :)
Продолжаю свой quest for #terminal.

#zutty

Напомню, что пока использую #foot, но и к нему у меня есть претензии(автор череcчур переусложнил логику инкрементальной перерисовки, и она у него иногда глючит).

Вот, новые кандидаты:

* https://github.com/tomscii/zutty - по коду (нормальный такой С++) хороший, качественный, терминал, но жестко прибит к X. "жестко" - надо переделать ввод, и настройку opengl контекста, все остальное делается поверх opengl. Модель рендеринга примитивная, без изъебов и шейдеров, как я уже пару раз описывал, и это очень хорошо! IMHO для переделки этого на SDL нужно 2 - 3 вечера. К сожалению, непонятно, примет ли автор такиеисправления, потому что он ну очень любит X, а просто так время было бы жалко тратить.

* https://github.com/91861/wayst - wayland + opengl, кодовая база на C, что заметно, потому что терминал не прошел мой стандартный тест:

-> cat some.big.tar.gz
...
[warning] Unknown escape sequence: (-40)
[warning] Unknown escape sequence: ␂ (2)
[warning] Unknown DCS: HH␖␒h␐j␍␊[40m␈q'␔i
␘"n[40m␆%_;␛K#F@␈
=e.Eϝ%[40m␐j?␜һ0␒(
ƽH␟ev␎mcf␓[40m␎␔GO␐pW␈
#Bq␚*x␎␓␛t␋␂i␅<zT[␈D(kx.,Z␎Lv^
ʤ_V sqb␡␋␒wI]lc]b'<?̮␜,␗ gKq␌
r4@EwqE␆pY߻V␚]␍␊~Z^␌?چRZpw')ҋ;8
V^K<{.y␍z·`G␄␃i>RTD:,,eAY␂c3n,̑[40m
␑␌MG,S␃2z`";=Yu`3␋x6␟F=1uL
[40m␋MiR␆TjL[40m␓x␍␊Ag␁␘.␃FN-ʪ
;Kc٥#0|4␖s.[40m␉1'U;<␏sb␑:Fh␙]␌e
␐D␛_ӿ[40m␍␊_ÿݟ[40m␡
[warning] Unknown escape sequence: (-62)
[warning] DECBI/DECFI not implemented
[warning] Unknown escape sequence: (-99)
[warning] Unknown escape sequence: (-85)
[warning] Unknown escape sequence: (-51)
[warning] Unknown escape sequence: (-102)
[warning] Unknown escape sequence: , (44)
[warning] Unknown escape sequence: (-24)
[warning] Unknown escape sequence: (-55)
[warning] Unknown escape sequence: (-70)
[warning] Unknown escape sequence: (-36)
[warning] Unknown escape sequence: K (75)
[warning] Unknown escape sequence: (-9)
[warning] Unknown escape sequence: (-124)
[warning] Unknown escape sequence: (-12)
[warning] Unknown escape sequence: (-46)
Segmentation fault

Да и какие-то странные артефакты рендеринга, как будто автор захотел быть святее папы римского freetype, и навернул там что-то типа (глючного и косого!) clear type.

Короче, какая-то пионерская поделка, а, на первый взгляд, выглядело хорошо!
👍10😁4🐳3🔥1
commit -m "better"
Продолжаю свой quest for #terminal. #zutty Напомню, что пока использую #foot, но и к нему у меня есть претензии(автор череcчур переусложнил логику инкрементальной перерисовки, и она у него иногда глючит). Вот, новые кандидаты: * https://github.com/tomscii/zutty…
#terminal #rant

https://www.jeffquast.com/post/ucs-detect-test-results/
https://ucs-detect.readthedocs.io/results.html

Монументальный текст (от автора python wcwidth) про то, как разные терминалы работают со всякими "странными" unicode последовательностями.

"Странными" в данном контексте я называю такие последовательности, которые занимают на экране терминала не столько же клеток, сколько в них юникодных символов. Последовательности нулевой ширины, эмодзи, какие-то широкие азиатские иероглифы, и так далее.

Unicode, в попытке объять необъятное (== унифицировано описать все разнообразие способов передать символьную информацию), идет куда-то не туда.

Вот раньше все было просто - 1 char == 1 клетка на экране (может быть, разной ширины, если не monospace). Потом стало сложнее, разных символов стало настолько много, что они перестали влезать в 1 байт, потом в 2. Были изобретены разные транспортные кодировки, типа utf8, но внутри лежал все тот же самый 4-байтный codepoint.

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

Логическое завершение этого процесса - это запихнуть вместо текста сниппет WebAssembly кода, который, в зависимости от контекста, сможет отрендерить себя на канве той или иной всратости.

Потому что как еще унифицировать анимированное эмодзи с какахой и, не знаю, символы нулевой ширины со всем остальным зоопарком, я не понимаю.

Как нужно?

1) Нужно пытаться перестать запихнуть в Unicode всякого рода symbol of the day, типа анимированной какахи.

2) Нужно сказать, что терминал - он не для вывода произвольного Unicode текста, а только для такого текста, который имеет разумное (две клетки на символ - неразумное, усложняет вообще все в разы) погружение в концепцию клеток фиксированной ширины. Для всего остального есть браузер.

(я, например, даже не расстроюсь, если в терминале останется только первые 128 символов из ASCII, но, врочем, я и полезность юникодных имен файлов до сих пор не очень осознал)
👍15😁5🔥4💩4🥰2🤔1🤯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
#bootstrap #terminal #rant #cosmic

https://www.phoronix.com/news/Pop-OS-24.04-Alpha-8-August

Тут вон пишут, что скоро выйдет альфа COSMIC desktop.

Мне, с одной стороны, очень импонирует эта штука, как глоток свежего воздуха после засилья GNOME/KDE.

С другой, оно безумно сырое, и не работает за пределами окружения своих же разработчиков:

https://gist.github.com/pg83/777521db03c528bbeadbf90befc551f7

Я, как вы знаете, очень люблю смотреть на новые эмуляторы терминала, но я так и не смог завести cosmic-term, потому что не смог передать ему хоть какой-то шрифт, который бы он нашел в моей системе. Не то что тот, что он хочет по умолчанию, а вообще хоть какой-то.

Нуачо, все перепишем на Rust, и проигнорируем традиционные способы эти шрифты найти.
🐳8👍42🤔1
https://mitchellh.com/writing/ghostty-is-coming #ghostty #terminal

Тут вот коллега хочет запилить еще один "самый лучший" эмулятор терминала.

В тексте, конечно, есть (притянутое за уши) сравнение, которое объясняет нам, почему же ghostty будет лучше всех, но, на самом деле, это сравнение выглядит так:

          Zig
Alacritty -
Kitty -
iTerm -
Ghostty X


Отдельно доставил пассаж про

"For "platform-native", Ghostty uses the native GUI toolkit on macOS and GTK (plus libadwaita if available) on Linux. This means that Ghostty looks and feels (and really is) a native application on both platforms. This is in contrast to many terminal emulators that use the native GUI toolkits only to create a window"

Вот что у этих людей творится в голове?
🤷‍♂17👍7💯5🐳3👻3🤷‍♀1
commit -m "better"
Тут вот коллега хочет запилить еще один "самый лучший" эмулятор терминала.
https://www.opennet.ru/opennews/art.shtml?num=62471

У #ghostty случился релиз.

Доставляет способ тестировать производительность терминала (нет, реально, все как у великих - https://t.iss.one/itpgchannel/306):

"В проведённых тестах Ghostty оказался быстрее эмуляторов терминала iTerm и Kitty в 4 раза, а Terminal.app - в 2 раза, при выводе на экран содержимого большого файла, например, при помощи команды "cat big_file.txt". При сравнении с Alacritty производительность Ghostty была примерно на том же уровне, но Alacritty отстаёт по функциональности от Ghostty"

В общем, пока эталонное "не нужно".

#terminal
🤡14😁9👍6🐳3👎1
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