256 цветов в терминале ⇒ уровень nightmare

в 17:50, , рубрики: shell, метки:

256 цветов в терминале ⇒ уровень nightmare
Я тут строю некоторый велосипед с длинным отладочным выводом в stdout и меня взволновал вопрос серьезной расцветки лога. Современные терминалы xterm умеют и любят 256 цветов, но вот люди, которые придумывали escape-последовательности для этой палитры, стреноженные обратной совместимостью и латентной склонностью к криптографической эмпирике, все сделали так, что у меня ушло несколько часов на то, чтобы со всем этим разобраться. Интернет тоже не изобилует подробными разъяснениями, как оно там устроено.
Вкратце, текст в иксовый терминал можно нынче выводить кучеряво. Я набросал некое подобие сервиса, типа визивига для генерации escape-последовательностей. Выбрал цвета, начертание шрифта — получи набор закорючек. Тех же, кому интересны потроха — прошу под кат.

Цвета в xterm

Чтобы терминал понимал, что он может показать 256 цветов, ему надо об этом сказать:

  case "$TERM" in
    'xterm') TERM=xterm-256color;;
    'screen') TERM=screen-256color;;
    'Eterm') TERM=Eterm-256color;;
  esac

Сам цвет кодируется совершенно умопомрачительным образом. Escape-последовательность, начинающаяся традиционно с e[ и заканчивающаяся m, состоит из флагов, цвета фона и цвета текста. Флаги для жирного, наклонного, подчеркнутого и инверсного (fg⇐⇒bg): 01, 03, 04, 07 соответственно (есть еще флаг для мигающего, но вдруг меня читают дети?). Флаги отмены этих стилей: 22, 23, 24, 27. Флаги можно записывать один за другим через точку с запятой, перед заключительной «m» точка с запятой не ставится.
Цвет текста имеет сигнатуру (пардон) 38;05; ЦВЕТ;. Цвет фона — 48;05; ЦВЕТ;. ЦВЕТ здесь — это ∀ целое число ∈ [1, 255]. Первые шестнадцать — хорошо нам знакомые старые терминальные цвета, последние 24 — градации серого, остальные — ну это остальные.
Вот как-то так (за картинку спасибо федоре):
256 цветов в терминале ⇒ уровень nightmare

Легко увидеть, что последовательность «e[01;04;38;05;196;48;05;232m» включит режим жирного подчеркнутого красного на черном фоне.

Как цвет-то получить?

Цвета, оказывается, кодируются в оставшиеся 255 ­- 16 - 24 = 216 цветов простым и понятным алгоритмом: градации rgb калибруются на шесть и цифра получается как RGB в шестиричной системе счисления, с «нулем в шестнадцати» (для #ff9900 это даст 16 + 5 * 6² + 3 * 6 + 0 = 214). Есть и исключения, как же без них. Те самые «стандартные» 16 цветов и градации серого. Ага.

Зачем это все?

Ну, во-первых, мне было любопытно. Во-вторых, три часа — не деньги. В-третьих, у меня теперь мой лог-файл так переливается, что выцепить что-нибудь взглядом стало еще сложнее. Ну и PS1, конечно, переписан с нуля.

В общем, если вам нужна escape-последовательность для конкретного цвета — вот вам WYSIWYG. Если кому-то зачем-то нужен оффлайн — @github.

Спасибо за внимание.

Автор: matiouchkine

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js