Не могу дождаться этого. Я взламывал hterm, пытаясь получить поддержку truecolor, но мне кажется, что это лучший вариант.
Реализовать это нужно здесь https://github.com/sourcelair/xterm.js/blob/365a9f949cc1acfb6c4649ee1d85da3bbc60f928/src/InputHandler.ts#L1276
Сложная часть состоит в том, чтобы определить, как мы сохраняем цвета по отношению к символу (символам), а затем как их отображать (возможно, встроенные атрибуты style
). Что-то вроде https://github.com/sourcelair/xterm.js/pull/450 , вероятно, упростило бы добавление атрибутов.
Я могу взглянуть на это, когда у меня будет время, но не могу сказать, что я слишком хорошо знаком с управляющими последовательностями.
Я взглянул на http://invisible-island.net/xterm/ctlseqs/ctlseqs.html, но, похоже, не нашел ничего об истинном цвете или 24-битном цвете. Я что-то упускаю или есть какой-то другой ресурс, посвященный этому?
@cnsumner xterm в настоящее время не может отображать истинный цвет, но поддерживает одну из предложенных управляющих последовательностей. Подробнее об этом можно прочитать здесь: https://gist.github.com/XVilka/8346728
Кстати, это частично указано в стандарте ECMA-48.
Соберите беспорядочное доказательство концепции, чтобы лучше понять, что нам нужно делать здесь https://github.com/Tyriar/xterm.js/tree/484_truecolor
Что нужно сделать:
0x1RRGGBB
(fg) или 0x0RRGGBB
(bg), что соответствует 32-битному целому числу.curTrueColor
супер уродливоВозможно, пришло время переосмыслить, как кодируются символы, текущий формат:
[attribute, character, width]
attribute
: 32-битное целое число, содержащее ascii fg, ascii bg и флаги (жирный, подчеркивание, мигание, инверсия, невидимость), используются не все биты.char
: либо пустая строка (для символов ширины 0, которые дополняют широкие символы), либо односимвольная строка Unicodewidth
: ширина символа в настоящее время может быть 0, 1 или 2, но это может включать больше для правильной поддержки вкладок https://github.com/sourcelair/xterm.js/issues/734@Tyriar
Да, использование памяти резко возрастет, если она не будет оптимизирована для низкого потребления. Может быть, его можно упаковать вместе с width
, это поле вряд ли станет больше 16, занимая только 4 байта (обычно вкладка по умолчанию 4 или 8). Это оставляет место для одного определения RGB * (при условии, что width
- 32-битное целое число). Не уверен, сколько битов свободно в attribute
, может быть, подойдет второе определение RGB .
Похоже, что атрибуты в настоящее время занимают 9 байтов для bg, 9 байтов для bg и 5 байтов для флагов, оставляя много, чтобы сжать ширину в конце. Для каждого определения RGB требуется 24 байта (8 * 3).
Вот (немного сложный) подход к экономии места, который, я думаю, вы предлагаете:
[char, attr1, attr2]
Где attr1 (29 бит):
А attr2 (30 бит):
Более простой подход будет использовать число специально для атрибутов:
[char, attr, truecolorBg, truecolorFg]
Где attr:
Я так сильно хочу инкапсулировать эти детали, поскольку они действительно усложняют ситуацию, мне интересно, позволит ли машинописный текст каким-то образом помещать геттеры в массив. Использование объекта было в 20 раз медленнее, чем массив на основе микротеста, который я провел на jsperf, я знаю, что они не всегда надежны, но это то, что я ожидал в качестве накладных расходов при создании объекта на основе прототипа.
Что бы мы ни делали, формат нужно очень хорошо задокументировать. Прямо сейчас вам нужно выяснить это самостоятельно, посмотрев на InputHandler.charAttributes
.
Еще несколько мыслей по экономии памяти:
null
.Да, я думаю, что на большинстве JS-движков массивы с доступом к индексу все еще быстрее, чем объекты и их свойства. Тем не менее, V8 получил некоторые дополнительные оптимизации для объектов. Построение и сборка мусора в массиве происходит быстрее из-за гораздо более простой структуры памяти (этот недостаток можно избежать, повторно используя существующие объекты).
Я понятия не имею о правильном макете здесь, проблема в том, что любой сильно упакованный материал приведет к увеличению времени выполнения из-за необходимых преобразований. (Это одна из причин не использовать битовые поля в C, если память не вызывает беспокойства - необходимые операции сдвига будут загрязнять кеш инструкций, что приведет к промахам кеша - код работает намного медленнее).
Имхо только тесты покажут, что здесь лучше всего работает.
@jerch интересно, у меня сейчас для простоты 4-х https://github.com/sourcelair/xterm.js/pull/756.
Таким образом, память здесь должна быть около: 5 * (1000 прокрутки) * (8 байт на 64-битной машине) * 80 = 3,2 МБ (до накладных расходов на массив js). Фактическая ширина типичного терминала VS Code увидит это вдвое, если мы сохраним текущий формат. Теперь, когда я смотрю на это, это кажется довольно крутым, особенно с учетом того, что у пользователей часто будет более 1000 прокрутки назад и несколько активных терминалов. Конечный пробел, который на самом деле ничего не добавляет, может быть также нулевым, что, вероятно, будет довольно большой победой.
Идея кеширования атрибутов / наборов цветов также кажется многообещающей, если есть хороший способ быстрого доступа. Легкая расширяемая древовидная структура была бы идеальной (быстрый доступ к атрибутам, которые используются наиболее часто).
Также, возможно, стоит подумать о повторном использовании массивов строковых данных, когда они обрезаны, вместо того, чтобы просто отбрасывать их ( например, здесь ).
Да, и с учетом накладных расходов движка, он становится еще больше - все в массиве или объекте хранится как ссылка, в основном указатель на контент. Плотные js-массивы имеют здесь небольшое преимущество, они формируются как C-подобный массив где-то по пути (ну, собственно, ArrayLists). Редкие массивы и другие объекты строятся с помощью некоторой древовидной магии для решения разрешения свойств.
Таким образом, для 64-битной эталонной вещи на ячейку добавляется еще 5 * 8 байтов (это в основном удваивает ваш расчет выше - 6,4 МБ). К содержимому можно добавить еще больше байтов помимо «реального содержимого», но это зависит от фактической реализации типов Integer и String.
Возможно, TypedArray может решить эту проблему. Здесь целочисленный материал может находиться непосредственно в позиции индекса в памяти без дополнительного косвенного обращения. asm.js в основном работает только с ними.
Вот небольшой тест для сравнения TypedArray и js-Array для создания и вставки данных: http://jsbench.github.io/#af3ea1056a70df2aa6775699d174df0d
TypedArray работает в 10 раз быстрее с FF и Chrome на моем компьютере. Это может быть связано с предварительным распределением, не тестировал это с помощью js-Array, так как это не рекомендуется. Не уверен, заметят ли JIT тот факт, что значение просто увеличивается на 1 каждые 8 байтов, и даже оптимизируют его. Тогда бенчмарк вообще бесполезен.
Доступ немного хуже для TypedArray (возможно, из-за преобразования Number
), потребление памяти намного лучше с TypedArray.
Обратной стороной TypedArray является статический блок памяти, когда дело доходит до резервных данных (уловки, позволяющие избежать данных вообще, здесь не работают, память в любом случае «теряется») или изменение размера с переносом содержимого. Трудно сделать это правильно и, вероятно, придется копировать большие фрагменты данных снова и снова.
Привет. Есть обновления по этому поводу? Не могу дождаться, когда это заработает 😃
Кто-нибудь активно работает над этим вопросом? Обсуждается ли это где-нибудь еще? @chabou @Tyriar? Помогает ли Microsoft использовать в VS Code?
Это последняя проблема, связанная с использованием Hyper в WSL в Windows 10, чтобы обеспечить достойный рабочий процесс CLI для разработчиков, поддерживающий tmux и vim / neovim. Другие эмуляторы терминала, доступные для использования с WSL, просто не приятно смотреть, wsltty близок, но поддержка вкладок и плагинов отсутствует ...
@vastbinderj Почему отсутствие поддержки истинного цвета не дает вам достойного рабочего процесса CLI разработчика? Честный вопрос.
@szmarczak и @vastbinderj
Этот вопрос все еще стоит на повестке дня, но он блокируется из-за высокого использования памяти, которое он представит с текущим дизайном буфера терминала. Это привлечет больше внимания, когда # 791 предоставит нам более эффективную компоновку буфера.
@rfgamaral simple - я работаю на множестве разных серверов unix / linux в день на очень больших корпоративных системах с множеством микросервисов и отсутствие достойной поддержки цвета на главном хосте - это разрушительно. Больно иметь дело с разными цветами, независимо от того, использую ли я rhel, centos или debian. Кроме того, если я сижу, чтобы помочь младшему или коллеге-разработчику по Windows, мне нужно переключать контекст, если что-то не работает единообразно. Тем не менее, я очень впечатлен тем, насколько быстро wsl продвинулся с улучшениями, выпускаемыми почти ежемесячно, и то же самое с VS Code, он выдающийся.
@jerch Спасибо за обновление, буду терпеливо ждать, пока проработает # 791 ...
С нетерпением жду этого.
Стоит помнить, что числа JavaScript могут представлять точные целые числа до 53 бит. Таким образом, у вас есть 21 бит в дополнение к 32 «удобным» битам. Вы можете добавить немного «или» простым добавлением, если оно еще не установлено. Чтобы прочитать старшие биты, просто разделите на подходящее целое число степени двойки, а затем используйте обычные битовые операции.
Конечно, при работе с битами более высокого порядка накладные расходы немного выше, но на современных процессорах деление на мощность или два относительно дешево - дешевле, чем доступ к памяти.
Я предлагаю использовать одно число с 50 битами: по 25 бит для переднего и заднего плана. Один бит, если установлен, означает, что мы используем 24-битный «истинный» цвет; если не установлен, мы используем «логические» (тематические) или 8-битные цвета. Биты индикатора должны быть двумя младшими битами; если не задано, логические / 8-битные цвета могут быть в следующих 30 битах, поэтому мы используем биты 32-50, только если мы действительно используем истинный цвет.
@PerBothner Мы решили использовать Uint32Array для нового буфера, а также для удобства помещать цвета в этот массив. Это еще не сделано, так как мы хотим сначала очистить новый impl, прежде чем поддерживать truecolor.
Также я провел несколько тестов / вычислений о возможных макетах (см. Https://gist.github.com/jerch/27c2cf91ad313a25415873e4047b2900). Короче говоря, идеи заключаются в компромиссе между сохранением памяти и штрафом во время выполнения. Переход к типизированному массиву уже дал огромную экономию памяти (в настоящее время реализуется вторая идея сверху, хотя истинные значения цвета еще не применяются).
Самый полезный комментарий
Привет. Есть обновления по этому поводу? Не могу дождаться, когда это заработает 😃