Pull to refresh

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

Reading time 2 min
Views 59K


Я тут строю некоторый велосипед с длинным отладочным выводом в 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 — градации серого, остальные — ну это остальные.
Вот как-то так (за картинку спасибо федоре):


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

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


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

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


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

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

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

Upd: frexx.de/xterm-256-notes — хорошая ссылка по теме. Спасибо, yermulnik.
Tags:
Hubs:
+118
Comments 79
Comments Comments 79

Articles