commit -m "better"
2.96K subscribers
868 photos
105 videos
3 files
2.07K links
just random thoughts
Download Telegram
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, хотя и несколько медленнее.
Галопом по Европам.

А вы знали, что можно писать не sed -e s///, а sed -e s|||? Я вот узнал всего полгода назад, и мне это уже сэкономило кучу нервов и сил на эскейпинге /. Наверняка это всем давно известно, и никому не интересно, но я вот не знал.

———
https://hacks.mozilla.org/2021/12/webassembly-and-back-again-fine-grained-sandboxing-in-firefox-95/

Мозилла начала делать какую-то очень странную вещь. Часть библиотек они компилируют не в исполняемый код, а в #WASM, и джитят во время работы. Это им дает возможность установить менее большую surface для особо опасного кода, и, типа, так безопаснее. Я имею сказать:

1) Норм тащить в проект 1000000 строк кода, чтобы обезопасить 10000? Впрочем, JIT для WASM и так и так бы был.

2) А почему бы не сделать на WASM весь браузер? https://pbs.twimg.com/media/ELxt9LSXUAMlmIp.jpg А, было же такое - https://en.wikipedia.org/wiki/HotJava , не полетело.

———
https://codeberg.org/dnkl/foot/pulls/461 #foot
https://gitlab.freedesktop.org/terminal-wg/specifications/-/merge_requests/2

#terminfo

Я тут пару раз писал про разные эмуляторы терминала, и сокрушался, что их авторы не хотят реализовывать нормальный протокол для tear-free rendering. Потом я написал, что, оказывается, разработчики терминалов в курсе этой проблемы, и даже изобрели syncronized updates, но почему-то все равно не хотят реализовывать правильный протокол. Я еще раз перечитал доступные тексты, и понял, что разработчики терминалов считают проблему решенной - кому надо(я, например), могут использовать syncronized updates, а проблемы негров(ncurses, например) шерифа не волнуют.

Пока читал, выяснил, что эти прекрасные люди не смогли договориться до одного варианта, и придумали аж целых два. Я оба и реализовал: #kitty #foot

https://github.com/pg83/ted/commit/a0aa84567efb7ac0760fde048dae0acf805fd188

В ncurses, наверное, не появится никогда.
Я тут собирал #kitty под Linux, прост потому что мне не нравится, когда в репозитории есть сломанные таргеты. Так-то я использую #foot

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

* Всю эту бодягу как писал индус #Ковид, так и продолжает писать индус, с метрикой в количество написанных строк кода. Я не знаю как еще обосновать свежеиспеченную зависимость этой программы от librsync.

* Мое любимое занятие(на самом деле нет) - делать так, чтобы эмуляторы терминала выглядели одинаково. Для этого при размере шрифта в foot 12pt мне пришлось выставить в kitty 11.8pt(на тот же шрифт). Не могу доказать, но чую, что автор kitty где-то что-то умножил на константу или сложил, потому что у него там границы символов не сходились, ну или просто так больше нравилось. Да, это prejustice prejudice.

* В kitty какое-то безумное чило настроек. Такое ощущение, что автор бездумно вместо терма X везде писал (X + X1) * X2, ну чтобы можно было настроить что угодно и как угодно, иначе я все эти бессмысленные настройки объяснить не могу.

* Я решил проверить kitty и foot на performance. Для этого я, конечно(MAD SKILZ detected), сделал cat some_big.pdf прямо в терминал. Kitty тупо завис(не, прямо реально завис), foot отработал неважно с какой скоростью. Лог kitty перед смертью:

[097 21:55:06.343874] [PARSE ERROR] 
Unknown char after ESC: 0x24
[097 21:55:06.343883] [PARSE ERROR]
Unknown char after ESC: 0x65
[097 21:55:06.347035] [PARSE ERROR]
Unrecognized APC code: 0x1a

* После этого я вывел 20 мегабайт случайного текста.

foot:
real 0m0.642s
user 0m0.000s
sys 0m0.198s
pg->

kitty:
real 0m0.644s
user 0m0.000s
sys 0m0.207s
pg->

Казалось бы, одинаковая скорость, что у GPU-accel kitty, что у CPU foot? Какое там, это только потребление CPU! Kitty еще съел невозбранно дофига GPU, которое я не умею измерять!

* Kitty весит 51MB, foot - 8. Помним, что у меня статическая линковка. Чем меньше кода, тем меньше багов.

* Вишенка на торте - размер https://github.com/kovidgoyal/kitty/blob/master/setup.py в Kitty 50KB. Чувак там реально запилил сборку .c и .py кода(херовую, конечно). Размер всего ядра MIX - 45KB. А я уже собрал 550 пакетов, у меня супер крутая сборка с декартовым произведением флагов и кросс-компиляцией.

* Еще хочу похвастаться, как у меня круто устроено наследование шаблонов и диспатч между таргетами. Для тех, кто не знает шаблоны ruby/jinja2/etc, {{super()}} - это "взять текст базового блока и подставить в это место".

https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/kitty/t/mix.sh - базовый шаблон
https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/kitty/linux/mix.sh - надстройка для linux
https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/kitty/darwin/mix.sh - для darwin
https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/kitty/mix.sh - диспатч между ними

Я все мог бы сделать в одном файле через if darwin, if linux, но так намного читаемее.

TL:DR; - не ведитесь, когда вам продают GPU accelerated что-то, чаще всего это хайп ни о чем.
👍8👏31
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
Мне тут посоветовали вместо #mosh использовать https://eternalterminal.dev

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

Он, знаете ли, падает у меня, причем очень настойчиво, я фикшу одну ошибку, он падает где-то еще:

pg-> et [email protected]
Could not reach the ET server:
pg.vla.yp-c.yandex.net:2022

pg-> et -u pg pg.vla.yp-c.yandex.net
Segmentation fault

Штоа?

* Падал при любой попытке вывести исключение. Почему?

376   numFrames = backtrace(stack, 
MAX_STACK_FRAMES);
377 memmove(stack, stack + 1,
sizeof(void *) * (numFrames - 1));

Ну, например, потому что у меня backtrace() возвращает 0, потому что без frame pointer вывести стектрейс - дорогое удовольствие, #musl не умеет. 0 - нормальный результат, https://man7.org/linux/man-pages/man3/backtrace.3.html

* Кидал исключение даже до того, как печатал —help. Почему? Потому что, перед тем, как сделать что-то разумное, пытался перенаправить stderr в файл, и, при этом, содержал некорректную реализацию GetTempDirectory() - https://github.com/MisterTea/EternalTerminal/blob/master/src/base/Headers.hpp#L384 (кто так делает, в 21 веке???), при попытке открыть файл в которой летело исключение. Далее смотри пункт 1. Вообще, неправильное получение tmp dir - этим много кто грешит, поэтому я даже запилил микробиблиотечку, которой патчу клиентов по месту - https://github.com/pg83/ix/blob/main/pkgs/bin/et/ix/ix.sh#L26 https://github.com/pg83/ix/tree/main/pkgs/lib/shim/ix

Настраивать логгирование до парсинга command line - это так-то клиника.

Оно у меня снова падает, и я не уверен, что хочу продолжать этот квест.
😁7🔥5👍3🤯1🍌1
commit -m "better"
https://github.com/kovidgoyal/kitty/issues/606 Зато из комментариев стало понятно, зачем этот господин форкнул glfw. Он не осилил сделать нормальный ввод для своей аццкой программы, и ему понадобилось одновременно получать информацию про scancode, и про текст.…
(технический пост, не думаю, что это особо интересно, скорее, запись для себя)

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

Но вот решил собрать его заново, с чистого листа, выкинув всякого рода хаки, которые были несистемны (потому что их нельзя было применить за пределами сборки kitty), и построив все на механизмах, наработанных за этот год.

https://github.com/pg83/ix/tree/main/pkgs/bin/kitty/prev - вот тут я прикопал старую сборку
https://github.com/pg83/ix/tree/main/pkgs/bin/kitty/next - а вот тут новую

Отдельных папочек (целей) стало больше, каждая цель стала описываться проще.

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

Новый вариант - это, по сути, 10 раз запустить родную сборку (это быстро), взять маленький ее кусочек, поработать с ним, и подготовить его к тому, чтобы моя generic машинерия могла с ним работать:

* https://github.com/pg83/ix/blob/main/pkgs/bin/kitty/next/modules/glfw/ix.sh - вот так я готовлю какой-то произвольный .so от родной сборки kitty
* https://github.com/pg83/ix/blob/main/pkgs/bin/kitty/next/modules/fdt/ix.sh - или другой. По папочке на каждый модуль, но там и код не очень обобщаем
* https://github.com/pg83/ix/blob/main/pkgs/bin/kitty/next/py/ix.sh - а вот так готовлю его питонячку, чтобы дальше мочь ее заморозить своим generic механизмом
* https://github.com/pg83/ix/blob/main/pkgs/bin/kitty/next/unwrap/ix.sh#L21 - а вот так выглядит переписанный entry point для kitty, в котором я его манкипатчу на предмет wayland, no x11, другой способ подморозки произвольных ресурсов, и так далее

В общем, оно получилось гораздо более composable, и переживет следующие upver существенно проще.

Первый способ у меня занял в 5 - 10 раз больше чистого времени.

Мораль?

Некоторые вещи нужно делать не когда очень хочется, а когда ты к этому готов!

Fun fact - #Ковид начала переписывать kitty на Go, я бы на его место тоже так сделал, потому что сейчас kitty - это unmanageable mess.
🔥5🤬3👍2
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