Вопрос или проблема
При использовании последовательностей escape для сохранения/восстановления курсора \e7
и \e8
я обнаружил, что они не только восстанавливают позицию курсора, но и восстанавливают текстовое форматирование (цвета).
Я пробовал это в WSL, в VSCode на Windows и в онлайн-ВМ с Ubuntu. Является ли это стандартизированным (в каком-то смысле «стандарта»)? Можно ли на это полагаться в большинстве терминалов, которые используются сегодня?
Вы даже не можете быть уверены, что ESC 7
и ESC 8
будут сохранять/восстанавливать позицию! Не все терминалы следуют одному и тому же стандарту. Вот почему в Unix существует база данных terminfo (а ранее termcap), позволяющая программам определять, что может делать каждый терминал.
В идеале вы должны использовать возможности terminfo «sc» (сохранить курсор) и «rc» (восстановить курсор) для получения значений, чтобы обеспечить большую портативность. Скорее всего, это будут \E7 и \E8, но вы не можете быть в этом уверены.
Таким образом, например
% infocmp -1 | egrep ' [sr]c="
rc=\E8,
sc=\E7,
Но старая определение terminfo для mskermit227|msk227|MS-DOS Kermit 2.27 для IBMPC
использует sc=\Ej
и rc=\Ek
.
У sperry uts30
есть rc=\EX
и sc=\EW
.
Некоторые типы терминалов вообще не поддерживают эту функциональность! Просмотр определений terminfo на моей машине с CentOS 7 показывает 16 определений без этой поддержки.
Вы вероятно столкнетесь с этими типами терминалов? Возможно, нет (хотя один из них «xterm-vt52»; кто-то, выбирающий это, просто пытается усложнить себе жизнь…). Большинство современных терминалов и терминальных эмуляторов (остальные 103 в моем списке terminfo) все поддерживают это.
На самом деле ESC 7
и ESC 8
— это команды режима DEC, которые пришли из серии VT. Для этого описание немного более конкретное:
ESC 8 – DECRC – DEC Восстановить Курсор – Восстанавливает позицию курсора, состояние кодирования сдвига и атрибуты форматирования из предыдущего DECSC, если таковые имеются, в противном случае сбрасывает все на значения по умолчанию
Таким образом, для любого терминального эмулятора, который правильно реализует это, мы можем быть уверены, что он сбросит цвет и атрибуты жирного/тусклого текста.
Тем не менее, для безопасности вы не должны предполагать это; после вызова “rc” вы должны явно установить любое форматирование, которое хотите продолжать использовать.
Ответ или решение
Когда мы рассматриваем команды для сохранения и восстановления курсора, такие как ESC 7
и ESC 8
, важно понимать, что их поведение может варьироваться в зависимости от терминала, используемого для отображения.
Действительно, эти команды (или escape-последовательности) предназначены для сохранения текущей позиции курсора (и, как правило, состояния форматирования, включая цвета) и восстановления их позже. Однако, нельзя полагаться на то, что такие функции будут одинаково поддерживаться во всех терминалах. Как было упомянуто в ваших экспериментах, вы обнаружили, что ESC 7
и ESC 8
восстанавливают не только позицию курсора, но и его форматирование. Это действительно так в большинстве современных терминалов, однако стандартизация в этом вопросе отсутствует.
Чтобы обеспечить максимальную совместимость, рекомендуется использовать возможности библиотеки terminfo (или termcap), которые предоставляют абстракцию для определения поддерживаемых функций каждого терминала. Например, возможности sc
(сохранить курсор) и rc
(восстановить курсор) должны использоваться, чтобы написать код, который будет работать на большем количестве терминалов. Это особенно важно, так как некоторые старые термины могут не поддерживать эти функции вообще, как вы уже упомянули.
Приведенные вами примеры терминов, таких как mskermit227
или sperry uts30
, показывают, что реализация функций может сильно различаться. Например, в некоторых случаях команды для сохранения и восстановления курсора могут иметь совершенно другие значения – такие как sc=\Ej
и rc=\Ek
в термине mskermit227
.
Для большей уверенности, вы можете использовать утилиту infocmp
, чтобы получить информацию о поддерживаемых командах на вашей системе, что позволит вам более точно понимать, как работать с конкретными терминами. Хотя большинство современных терминалов поддерживают функции ESC 7
и ESC 8
, всегда разумно делать дополнительные проверки или явно задавать необходимые атрибуты форматирования после вызова rc
.
Таким образом, для вашего вопроса: да, команды ESC 7
и ESC 8
могут восстанавливать форматирование, если терминал правильно их реализует. Тем не менее, для обеспечения кросс-совместимости и минимизации рисков, рекомендуется использовать механизмы terminfo и всегда проверять спецификации терминала, с которым вы работаете.