Последовательности виртуального терминала в консоли
Последовательности виртуальных терминалов — это последовательности символов управления, которые могут управлять перемещением курсора, цветом консоли и другими операциями при записи в выходной поток. Последовательности можно также получить из входного потока в ответ на последовательность сведений запроса потока вывода или в виде кодировки входных данных пользователя (если установлен соответствующий режим).
Для настройки такого поведения можно использовать функции GetConsoleMode и SetConsoleMode. В конце этого документа приведен пример предлагаемого способа включения поведения виртуальных терминалов.
Поведение следующих последовательностей основано на VT100 и производных технологиях эмулятора терминала, в частности эмулятора терминала xterm. Дополнительные сведения о последовательностях терминала можно найти по адресу http://vt100.net и http://invisible-island.net/xterm/ctlseqs/ctlseqs.html.
Выходные последовательности
Следующие последовательности терминалов перехватываются узлом консоли при записи в выходной поток, если флаг ENABLE_VIRTUAL_TERMINAL_PROCESSING установлен в дескриптор буфера экрана с помощью функции SetConsoleMode. Обратите внимание, что флаг DISABLE_NEWLINE_AUTO_RETURN также может оказаться полезным для эмулирования расположения курсора и прокрутки других эмуляторов терминала в отношении символов, записанных в последний столбец в любой строке.
Простое позиционирование курсора
Во всех следующих описаниях ESC всегда имеет шестнадцатеричное значение 0x1B. В последовательностях терминала не должно быть пробелов. Отдельные последовательности терминалов могут быть разделены по любому символу или байтам по нескольким последовательным вызовам WriteFile или WriteConsole, но рекомендуется включить всю последовательность в один вызов. Чтобы узнать, как использовать эти последовательности на практике, ознакомьтесь с примером в конце этой статьи.
В следующей таблице описаны простые escape-последовательности с одной командой действия непосредственно после символа ESC. Эти последовательности не имеют параметров и вступают в силу немедленно.
Все команды в этой таблице обычно эквивалентны вызову API консоли SetConsoleCursorPosition для размещения курсора.
Перемещение курсора будет ограничено текущим окном просмотра в буфере. Прокрутка (если доступна) не будет выполняться.
Sequence | Сокращение | Поведение |
---|---|---|
ESC M | RI | Обратный индекс — выполняет обратную операцию \n, перемещает курсор вверх по одной строке, сохраняет горизонтальное положение, буфер прокрутки при необходимости* |
ESC 7 | DECSC | Сохранение позиции курсора в памяти** |
ESC 8 | DECSR | Восстановление позиции курсора из памяти** |
Примечание.
* Если есть поля прокрутки, ri внутри полей прокрутит только содержимое полей и оставьте окно просмотра без изменений. (См. раздел "Поля прокрутки".)
**Нет значения, сохраненного в памяти, пока не будет выполнено первое использование команды сохранения. Единственный способ получить доступ к сохраненному значению — выполнить команду восстановления.
Позиционирование курсора
В указанных ниже таблицах приведены последовательности типа CSI (начала управляющей последовательности). Все последовательности CSI начинаются с ESC (0x1B), за которым следует [ (левая скобка, 0x5B) и могут содержать параметры переменной длины, чтобы указать дополнительные сведения для каждой операции. Это будет представлено в виде сокращения <n>. Каждая таблица ниже сгруппирована по функциональности. Ниже таблицы указаны примечания, объясняющие, как работает эта группа.
Для всех параметров применяются следующие правила, если не указано иное:
- <n> представляет расстояние для перемещения и является необязательным параметром;
- если параметр <n> опущен или равен 0, он будет рассматриваться как 1;
- <n> не может превышать 32 767 (максимальное короткое значение);
- <n> не может быть отрицательным.
Все команды в этом разделе обычно эквивалентны вызову API консоли SetConsoleCursorPosition.
Перемещение курсора будет ограничено текущим окном просмотра в буфере. Прокрутка (если доступна) не будет выполняться.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ <n> A | CUU | Перемещение курсора вверх | Перемещение курсора вверх на <n> позиций |
ESC [ <n> B | CUD | Перемещение курсора вниз | Перемещение курсора вниз на <n> позиций |
ESC [ <n> C | CUF | Перемещение курсора вперед | Перемещение курсора вперед (вправо) на <n> позиций |
ESC [ <n> D | CUB | Перемещение курсора назад | Перемещение курсора назад (влево) на <n> позиций |
ESC [ <n> E | CNL | Перемещение курсора на следующую строку | Перемещение курсора вниз на <n> строк от текущей позиции |
ESC [ <n> F | CPL | Перемещение курсора на предыдущую строку | Перемещение курсора вверх на <n> строк от текущей позиции |
ESC [ <n> G | CHA | Перемещение курсора по горизонтали (абсолютное позиционирование) | Курсор перемещается на <n>-ю позицию по горизонтали в текущей строке |
ESC [ <n> d | VPA | Вертикальное положение строки (абсолютное позиционирование) | Курсор перемещается на <n>-ю позицию по вертикали в текущем столбце |
ESC [ <y> ; <x> H | CUP | Позиция курсора | *Курсор перемещается на <x>; <Координата y в области просмотра, где <x> — столбец <строки y>> |
ESC [ <y>; <x f> | HVP | Горизонтально-вертикальная позиция | *Курсор перемещается на <x>; <Координата y в области просмотра, где <x> — столбец <строки y>> |
ESC [ s | ANSISYSSC | Сохранение курсора — эмуляция Ansi.sys | **Без параметров выполняет операцию сохранения курсора, например DECSC |
ESC [ u | ANSISYSRC | Восстановление позиции курсора — эмуляция Ansi.sys | **Без параметров выполняет операцию курсора восстановления, например DECRC |
Примечание.
*<X> и y> имеют те же ограничения, что <и <n> выше. Если параметры <x> и <y> не указаны, им будут присвоены значения 1;1.
**ANSI.sys историческую документацию можно найти https://msdn.microsoft.com/library/cc722862.aspx и реализовать для удобства и совместимости.
Видимость курсора
Следующие команды управляют видимостью курсора и его мигающим состоянием. Последовательности DECTCEM обычно эквивалентны вызову API консоли SetConsoleCursorInfo для переключения видимости курсора.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ ? 12 h | ATT160 | Текстовый курсор: включение мигания | Запуск мигания курсора |
ESC [ ? 12 l | ATT160 | Текстовый курсор: отключение мигания | Остановка мигания курсора |
ESC [ ? 25 h | DECTCEM | Текстовый курсор: включение режима отображения | Отображение курсора |
ESC [ ? 25 l | DECTCEM | Текстовый курсор: включение скрытого режима | Скрытие курсора |
Совет
Последовательности включения заканчиваются символом строчной буквы H (h
), а последовательности отключения — символом L (l
).
Фигура курсора
Следующие команды управляют и позволяют настраивать фигуру курсора.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ 0 SP q | DECSCUSR | Фигура пользователя | Фигура курсора по умолчанию, настроенная пользователем |
ESC [ 1 SP q | DECSCUSR | Блок мигания | Фигура курсора блока мигания |
ESC [ 2 SP q | DECSCUSR | Устойчивый блок | Устойчивая фигура курсора блока |
ESC [ 3 SP q | DECSCUSR | Подчеркивание мигания | Фигура курсора подчеркивания мигания |
ESC [ 4 SP q | DECSCUSR | Устойчивое подчеркивание | Фигура курсора устойчивого подчеркивания |
ESC [ 5 SP q | DECSCUSR | Мигающий бар | Фигура курсора индикатора мигания |
ESC [ 6 SP q | DECSCUSR | Устойчивый бар | Фигура курсора устойчивой панели |
Примечание.
SP
— символ пробела литерала (0x20) в промежуточной позиции, за которым следует q
(0x71) в конечной позиции.
Позиционирование окна просмотра
Все команды в этом разделе обычно эквивалентны вызову API консоли ScrollConsoleScreenBuffer для перемещения содержимого буфера консоли.
Внимание! Имена команд недостоверны. Прокрутка — это направление, в котором текст перемещается во время операции, а не возможное направление перемещения окна просмотра.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ <n> S | SU | Прокрутка вверх | Прокрутка текста вверх на <n> позиций. Это действие также называется сдвигом вниз, новые строки появляются в нижней части экрана. |
ESC [ <n> T | SD | Прокрутите вниз | Прокрутка вниз на <n> позиций. Это действие также называется сдвигом вверх, новые строки появляются в верхней части экрана. |
Текст перемещается, начиная со строки, в которой расположен курсор. Если курсор находится в средней строке окна просмотра, то прокрутка вверх приведет к перемещению нижней половины окна просмотра и вставке пустых строк в нижней части. Прокрутка вниз приведет к перемещению верхней половины строк окна просмотра и вставке новых строк в верхней части.
Кроме того, обратите внимание, что прокрутка вверх и вниз также влияет на поля прокрутки. Прокрутка вверх и вниз не влияет на строки за пределами полей прокрутки.
Значение по умолчанию для <n> равно 1 (его можно опустить).
Изменение текста
Все команды в этом разделе обычно эквивалентны вызову API-интерфейсов консоли FillConsoleOutputCharacter, FillConsoleOutputAttribute и ScrollConsoleScreenBuffer для изменения содержимого буфера текста.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ <n> @ | ICH | Вставка символа | Вставка <n> пробелов в текущую позицию курсора со сдвигом всего существующего текста вправо. Текст, который выходит за экран справа, удаляется. |
ESC [ <n> P | DCH | Удаление символа | Удаление <n> символов в текущей позиции курсора со сдвигом пробелов с правого края экрана. |
ESC [ <n> X | ECH | Стереть символ | Очистка <n> символов из текущей позиции курсора с заменой их символом пробела. |
ESC [ <n> L | IL | Вставка строки | Вставка <n> строк в буфер в позицию курсора. Строка, на которой находится курсор, и строки под ней будут сдвинуты вниз. |
ESC [ <n> M | DL | Удалить строку | Удаляет <n> строк из буфера, начиная со строки, в которой находится курсор. |
Примечание.
Для IL и DL затрагиваются только строки в полях прокрутки (см. раздел "Поля прокрутки"). Если поля не заданы, то границами полей по умолчанию является текущее окно просмотра. Если линии будут сдвинуты ниже полей, они удалятся. При удалении строк в нижней части полей вставляются пустые строки, а строки за пределами окна просмотра никогда не затрагиваются.
Значение по умолчанию для <n> для каждой последовательности равно 0 (если оно опущено).
Для следующих команд параметр <n> имеет три допустимых значения:
- 0 — очищает все данные с текущей позиции курсора (включительно) до конца строки или экрана;
- 1 — очищает все данные с начала строки или экрана до текущей позиции курсора (включительно);
- 2 — очищает всю строку или экран.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ <n> J | ED | Стереть на экране | Заменяет весь текст в текущем окне просмотра или на экране, указанный параметром <n>, пробелами. |
ESC [ <n> K | EL | Стереть в строке | Заменить весь текст в строке с курсором, указанный параметром <n>, пробелами |
Форматирование текста
Все команды в этом разделе обычно эквивалентны вызову API консоли SetConsoleTextAttribute для изменения форматирования всех будущих операций записи в буфер текста, выводимого на консоль.
Отличие этой команды заключается в том, что позиция <n>, указанная ниже, может принимать от 0 до 16 параметров, разделенных точкой с запятой.
Если параметры не указаны, все они обрабатываются как единственный параметр 0.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ <n> m | SGR | Установка графического отображения | Установка формата экрана и текста, как указано <n> |
Указанная ниже таблица значений может использоваться для <n>, чтобы отобразить различные режимы форматирования.
Режимы форматирования применяются слева направо. Если применить конкурирующие параметры форматирования, крайний правый параметр будет приоритетным.
Для параметров, задающих цвета, будут использованы цвета, указанные в таблице цветов консоли, которую можно изменить с помощью API SetConsoleScreenBufferInfoEx. Если таблица изменена так, что "синяя" позиция в таблице отображает оттенок красного цвета RGB, то все вызовы синего цвета переднего плана будут отображать этот красный цвет до тех пор, пока не будет указано иное.
значение | Описание | Поведение |
---|---|---|
0 | По умолчанию | Возвращает все атрибуты в состояние по умолчанию до изменения |
1 | Глубокий/яркий | Применяет флаг яркости/интенсивности к цвету переднего плана |
22 | Неглубокий/неяркий | Удаляет флаг яркости/интенсивности для цвета переднего плана |
4 | Подчеркнутый | Добавляет подчеркивание |
24 | Нет подчеркивания | Удаляет подчеркивание |
7 | Отрицательные | Меняет местами цвет переднего плана и фона |
27 | Позитив (не негатив) | Возвращает передний план и фон в обычное состояние |
30 | Черный цвет переднего плана | Применяет неглубокий/яркий черный цвет для переднего плана |
31 | Красный цвет переднего плана | Применяет неглубокий/яркий красный цвет для переднего плана |
32 | Зеленый цвет переднего плана | Применяет неглубокий/яркий зеленый цвет для переднего плана |
33 | Желтый цвет переднего плана | Применяет неглубокий/яркий желтый цвет для переднего плана |
34 | Синий цвет переднего плана | Применяет неглубокий/яркий синий цвет для переднего плана |
35 | Пурпурный цвет переднего плана | Применяет неглубокий/яркий пурпурный цвет для переднего плана |
36 | Голубой цвет переднего плана | Применяет неглубокий/яркий голубой цвет для переднего плана |
37 | Белый цвет переднего плана | Применяет неглубокий/яркий белый цвет для переднего плана |
38 | Дополнительные цвета для переднего плана | Применяет дополнительные значения цвета для переднего плана (см. сведения ниже) |
39 | Цвет текста по умолчанию для переднего плана | Применяет для переднего плана только цвета по умолчанию (см. 0) |
40 | Черный цвет фона | Применяет неглубокий/яркий черный цвет для фона |
41 | Красный цвет фона | Применяет неглубокий/яркий красный цвет для фона |
42 | Зеленый цвет фона | Применяет неглубокий/яркий зеленый цвет для фона |
43 | Желтый цвет фона | Применяет неглубокий/яркий желтый цвет для фона |
44 | Синий цвет фона | Применяет неглубокий/яркий синий цвет для фона |
45 | Пурпурный цвет фона | Применяет неглубокий/яркий пурпурный цвет для фона |
46 | Голубой цвет фона | Применяет неглубокий/яркий голубой цвет для фона |
47 | Белый цвет фона | Применяет неглубокий/яркий белый цвет для фона |
48 | Дополнительные цвета для фона | Применяет дополнительные значения цвета для фона (см. сведения ниже) |
49 | Цвет текста по умолчанию для фона | Применяет для фона только цвета по умолчанию (см. 0) |
90 | Ярко-черный цвет переднего плана | Применяет глубокий/яркий черный цвет для переднего плана |
91 | Ярко-красный цвет переднего плана | Применяет глубокий/яркий красный цвет для переднего плана |
92 | Ярко-зеленый цвет переднего плана | Применяет глубокий/яркий зеленый цвет для переднего плана |
93 | Ярко-желтый цвет переднего плана | Применяет глубокий/яркий желтый цвет для переднего плана |
94 | Ярко-синий цвет переднего плана | Применяет глубокий/яркий синий цвет для переднего плана |
95 | Ярко-пурпурный цвет переднего плана | Применяет глубокий/яркий пурпурный цвет для переднего плана |
96 | Ярко-голубой цвет переднего плана | Применяет глубокий/яркий голубой цвет для переднего плана |
97 | Ярко-белый цвет переднего плана | Применяет глубокий/яркий белый цвет для переднего плана |
100 | Ярко-черный цвет фона | Применяет глубокий/яркий черный цвет для фона |
101 | Ярко-красный цвет фона | Применяет глубокий/яркий красный цвет для фона |
102 | Ярко-зеленый цвет фона | Применяет глубокий/яркий зеленый цвет для фона |
103 | Ярко-желтый цвет фона | Применяет глубокий/яркий желтый цвет для фона |
104 | Ярко-синий цвет фона | Применяет глубокий/яркий синий цвет для фона |
105 | Ярко-пурпурный цвет фона | Применяет глубокий/яркий пурпурный цвет для фона |
106 | Ярко-голубой цвет фона | Применяет глубокий/яркий голубой цвет для фона |
107 | Ярко-белый цвет фона | Применяет глубокий/яркий белый цвет для фона |
Дополнительные цвета
Некоторые эмуляторы виртуального терминала поддерживают палитру, превышающую 16 цветов, которые предоставляет консоль Windows. Для этих дополнительных цветов консоль Windows выберет ближайший подходящий цвет из существующей 16-цветной таблицы для отображения. В отличие от приведенных выше стандартных значений SGR, после первоначального обозначения дополнительные значения будут использовать дополнительные параметры в соответствии с таблицей ниже.
Подпоследовательность SGR | Description |
---|---|
38 ; 2 ; <r> ; <g> ; <b> | Задайте для цвета переднего плана значение RGB, указанное в <r>, <g>, <b> parameters* |
48 ; 2 ; <r> ; <g> ; <b> | Задайте для цвета фона значение RGB, указанное в <r>, g>, <<b> parameters* |
38 ; 5 ; <s> | Задайте цвет переднего плана индексу <> в таблице цветов 88 или 256* |
48 ; 5 ; <s> | Задайте цвет фона> индексу <в таблице цветов 88 или 256* |
*Палитры цветов 88 и 256, поддерживаемые внутренне для сравнения, основаны на эмуляторе терминала xterm. В настоящее время невозможно изменить таблицы сравнения/округления.
Цвета экрана
Приведенная ниже команда позволяет приложению установить для значения палитры цветов экрана любое значение RGB.
Значения RGB должны быть в шестнадцатеричном формате в диапазоне от 0
до ff
и разделяться символом косой черты (например, rgb:1/24/86
).
Обратите внимание, что эта последовательность является последовательностью OSC "Команда операционной системы", а не CSI, как и многие другие последовательности, перечисленные, и как таковое, начинается с "\x1b], а не "\x1b[". Как последовательности OSC, они заканчиваются строковым терминатором, представленным как <ST>
и передаваемые с ESC \
(0x1B 0x5C
). Вместо признака конца строки можно использовать BEL
(0x7
), но рекомендуется использовать более длинную форму.
Последовательность | Description | Поведение |
---|---|---|
ESC ] 4; <i>; rgb: <r> / g> / <<b><ST> | Изменение цветов экрана | Задает индекс палитры цветов экрана <i> для значений RGB, указанных в <r>, <g>, <b> |
Изменения режима
Существуют последовательности, управляющие режимами ввода. Существует два разных набора режимов ввода: режим клавиш курсора и режим клавиш дополнительной клавиатуры. Режим клавиш курсора управляет последовательностями, которые сформированы клавишами со стрелками, а также клавишами Home и End. Режим клавиш дополнительной клавиатуры управляет в основном последовательностями, созданными клавишами цифровой клавиатуры, а также функциональными клавишами.
Каждый из этих режимов представляет собой простые логические параметры: режим клавиш курсора — "Обычный" (по умолчанию) или "Приложение", а режим клавиш дополнительной клавиатуры — "Числовой" (по умолчанию) или "Приложение".
Последовательности, созданные в этих режимах, см. в разделах о клавишах курсора и о цифровых и функциональных клавишах.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC = | DECKPAM | Включение режима приложения для дополнительной клавиатуры | Клавиши дополнительной клавиатуры будут создавать последовательности в режиме приложения. |
ESC > | DECKPNM | Включение числового режима для дополнительной клавиатуры | Клавиши дополнительной клавиатуры будут создавать последовательности в числовом режиме. |
ESC [ ? 1 ч | DECCKM | Включение режима приложения для клавиш курсора | Клавиши дополнительной клавиатуры будут создавать последовательности в режиме приложения. |
ESC [ ? 1 l | DECCKM | Выключение режима приложения для клавиш курсора (использование обычного режима) | Клавиши дополнительной клавиатуры будут создавать последовательности в числовом режиме. |
Состояние запроса
Все команды в этом разделе обычно эквивалентны вызову API консоли Get* для получения сведений о состоянии текущего состояния буфера консоли.
Примечание.
Эти запросы будут выдавать свои ответы в поток входных данных консоли сразу после того, как он распознается в выходном потоке, а ENABLE_VIRTUAL_TERMINAL_PROCESSING задано. Флаг ENABLE_VIRTUAL_TERMINAL_INPUT не применяется к командам запросов, так как предполагается, что приложение, выполняющее запрос, всегда хочет получить ответ.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ 6 n | DECXCPR | Отчет о позиции курсора | Выведите позицию курсора следующим образом: ESC [ <r> ; <c> R Where <r> = строка курсора и <c> = столбец курсора |
ESC [ 0 c | DA | Атрибуты устройства | Сообщает об идентификаторе терминала. Выдаст "\x1b[?1; 0c, указывающий "VT101 без параметров". |
Символы табуляции
Хотя консоль Windows традиционно ожидает, что вкладки будут исключительно восемь символов широкими, *nix приложения, использующие определенные последовательности, могут управлять тем, где остановки вкладок находятся в окнах консоли для оптимизации перемещения курсора приложением.
Следующие последовательности позволяют приложению задавать расположения позиции табуляции в окне консоли, удалять их, а также перемещаться между ними.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC H | HTS | Установка горизонтальной табуляции | Задает позицию табуляции в текущем столбце, в котором находится курсор. |
ESC [ <n> I | CHT | Горизонтальная табуляция курсора (вперед) | Перемещение курсора к следующему столбцу (в той же строке) в соответствии с позицией табуляции. Если больше нет позиций табуляции, выполняется перемещение к последнему столбцу в строке. Если курсор находится в последнем столбце, выполняется перемещение к первому столбцу следующей строки. |
ESC [ <n> Z | CBT | Обратная табуляция курсора | Перемещение курсора к предыдущему столбцу (в той же строке) в соответствии с позицией табуляции. Если больше нет позиций табуляции, выполняется перемещение курсора к первому столбцу. Если курсор находится в первом столбце, то он не перемещается. |
ESC [ 0 г | TBC | Очистка позиции табуляции (текущий столбец) | Очищает позицию табуляции в текущем столбце, если она есть. В противном случае ничего не происходит. |
ESC [ 3 г | TBC | Очистка позиции табуляции (все столбцы) | Очищает все установленные позиции табуляции. |
- Для CHT и CBT <n> является необязательным параметром (по умолчанию равно 1), указывающим, сколько раз следует передвинуть курсор в указанном направлении.
- Если позиции табуляции не заданы через HTS, то CHT и CBT будут рассматривать первый и последний столбцы окна как единственные позиции табуляции.
- При использовании HTS для установки остановки табуляции консоль также приведет к переходу к следующей остановке табуляции в выходных данных символа TAB (0x09, '\t') таким же образом, как CHT.
Назначение набора символов
Следующие последовательности позволяют программе изменять сопоставление активного набора символов. Это позволяет программе выдавать 7-битные символы кодировки ASCII, но отображать их как другие глифы на экране терминала. В настоящее время единственными поддерживаемыми наборами символов являются ASCII (по умолчанию) и специальный набор графических символов в кодировке DEC. Список всех символов, представленных в наборе графических символов в кодировке DEC, см. по этому адресу http://vt100.net/docs/vt220-rm/table2-4.html.
Последовательность | Description | Поведение |
---|---|---|
ESC ( 0 | Назначение набора символов — рисование линии DEC | Включает режим рисования линии DEC |
ESC ( B | Назначение набора символов — US ASCII | Включает режим ASCII (по умолчанию) |
Обратите внимание, что режим рисования линии DEC используется для очерчивания границ в консольных приложениях. В следующей таблице показано, какой символ ASCII соответствует символу рисования линии.
Hex | ASCII | Рисование линии DEC |
---|---|---|
0x6a | j | ┘ |
0x6b | тыс. | ┐ |
0x6c | l | ┌ |
0x6d | m | └ |
0x6e | n | ┼ |
0x71 | к | ─ |
0x74 | t | ├ |
0x75 | u | ┤ |
0x76 | v | ┴ |
0x77 | w | ┬ |
0x78 | x | │ |
Поля прокрутки
Следующие последовательности позволяют программе настроить область прокрутки экрана, на которую влияют операции прокрутки. Это подмножество строк, которые настраиваются, когда экран будет прокручиваться в противном случае, например, на "\n" или RI. Эти поля также влияют на строки, измененные при выполнении операций вставки строки (IL), удаления строки (DL), прокрутки вверх (SU) и прокрутки вниз (SD).
Поля прокрутки могут особенно пригодиться для отображения части экрана, которая не прокручивается при заполнении остальной части экрана. Например, заголовок окна вверху или строка состояния в нижней части приложения.
Для DECSTBM есть два необязательных параметра: <t> и <b>. Они используются для указания строк, представляющих верхние и нижние строки области прокрутки (включительно). Если параметры не указаны, <t> по умолчанию равно 1, а <b> — текущей высоте окна просмотра.
Поля прокрутки задаются для каждого буфера, поэтому важно, чтобы альтернативный и основной буфер поддерживали отдельные параметры полей прокрутки (таким образом полноэкранное приложение в альтернативном буфере не навредит полям основного буфера).
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ <t> ; <b> r | DECSTBM | Установка области прокрутки | Задает поля прокрутки VT в окне просмотра. |
Заголовок окна
Указанные ниже команды позволяют приложению задать для заголовка окна консоли значение указанного параметра <string>. Допустимое количество символов в строке не должно превышать 255. Это эквивалентно вызову SetConsoleTitle с заданной строкой.
Обратите внимание, что эти последовательности являются последовательностями OSC "Команда операционной системы", а не CSI, как и многие другие последовательности, перечисленные, и как это начинается с "\x1b], а не "\x1b[". Как последовательности OSC, они заканчиваются строковым терминатором, представленным как <ST>
и передаваемые с ESC \
(0x1B 0x5C
). Вместо признака конца строки можно использовать BEL
(0x7
), но рекомендуется использовать более длинную форму.
Последовательность | Description | Поведение |
---|---|---|
ESC ] 0; <Строка><ST> | Установка заголовка окна | Задает для заголовка окна консоли значение <string>. |
ESC ] 2; <Строка><ST> | Установка заголовка окна | Задает для заголовка окна консоли значение <string>. |
Завершающий символ здесь — символ "Колокол", "\x07"
Альтернативный буфер экрана
*Приложения стилей Nix часто используют альтернативный буфер экрана, чтобы они могли изменять все содержимое буфера, не влияя на запущенное приложение. Альтернативный буфер точно соответствует размеру окна без области обратной прокрутки.
В качестве примера такого поведения рассмотрим запуск Vim из Bash. Vim использует весь экран для редактирования файла, а затем возвращается к Bash, не затрагивая исходный буфер.
Последовательность | Description | Поведение |
---|---|---|
ESC [ ? 1 0 4 9 h | Использование альтернативного буфера экрана | Переключается на новый альтернативный буфер экрана. |
ESC [ ? 1 0 4 9 l | Использование основного буфера экрана | Переключается на основной буфер. |
Ширина окна
Для управления шириной окна консоли можно использовать следующие последовательности. Они примерно эквивалентны вызову API консоли SetConsoleScreenBufferInfoEx для установки ширины окна.
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ ? 3 h | DECCOLM | Установка для числа столбцов значения 132 | Задает ширину консоли в 132 столбца. |
ESC [ ? 3 l | DECCOLM | Установка для числа столбцов значения 80 | Задает ширину консоли в 80 столбцов. |
Программный сброс
Для сброса некоторых свойств к значениям по умолчанию можно использовать указанную ниже последовательность. Следующие свойства сбрасываются к значениям по умолчанию (также перечислены последовательности, управляющие этими свойствами):
- Видимость курсора: видимый (DECTEM).
- Числовая клавиатура: числовой режим (DECNKM)
- Режим ключей курсора: обычный режим (DECCKM)
- Верхние и нижние поля: top=1, Bottom=Console height (DECS ТБ M)
- Набор символов: US ASCII
- Представление графики: по умолчанию или отключению (SGR)
- Сохранение состояния курсора: положение дома (0,0) (DECSC)
Sequence | Код | Описание | Поведение |
---|---|---|---|
ESC [ ! п | DECSTR | Программный сброс | Сбрасывает некоторые параметры терминала к значениям по умолчанию. |
Входные последовательности
Следующие последовательности терминалов создаются узлом консоли во входном потоке, если флаг ENABLE_VIRTUAL_TERMINAL_INPUT установлен в дескриптор входного буфера с помощью флага SetConsoleMode.
Существует два внутренних режима, определяющих, какие последовательности выдаются для заданных клавиш ввода: режим клавиш курсора и режим клавиш дополнительной клавиатуры. Они подробно описаны в разделе "Изменения режима".
Клавиши курсора
Ключ. | Обычный режим | Режим приложения |
---|---|---|
Стрелка вверх | ESC [ A | ESC O A |
Стрелка вниз | ESC [ B | ESC O B |
Стрелка вправо | ESC [ C | ESC O C |
Стрелка влево | ESC [ D | ESC O D |
HOME | ESC [ H | ESC O H |
Завершить | ESC [ F | ESC O F |
Кроме того, если нажать клавишу Ctrl с любой из этих клавиш, будут выданы указанные ниже последовательности, независимо от режима клавиш курсора:
Ключ. | Любой режим |
---|---|
CTRL+СТРЕЛКА ВВЕРХ | ESC [ 1; 5 A |
CTRL+СТРЕЛКА ВНИЗ | ESC [ 1; 5 B |
CTRL+СТРЕЛКА ВПРАВО | ESC [ 1; 5 C |
CTRL +СТРЕЛКА ВЛЕВО | ESC [ 1; 5 D |
Клавиши цифровой клавиатуры и функциональные клавиши
Ключ. | Sequence |
---|---|
Backspace | 0x7f (DEL) |
Пауза | 0x1a (SUB) |
ESCAPE | 0x1b (ESC) |
Insert | ESC [ 2 ~ |
DELETE | ESC [ 3 ~ |
Page Up | ESC [ 5 ~ |
Page Down | ESC [ 6 ~ |
F1 | ESC O P |
F2 | ESC O Q |
F3 | ESC O R |
F4 | ESC O S |
F5 | ESC [ 1 5 ~ |
F6 | ESC [ 1 7 ~ |
F7 | ESC [ 1 8 ~ |
F8 | ESC [ 1 9 ~ |
F9 | ESC [ 2 0 ~ |
F10 | ESC [ 2 1 ~ |
F11 | ESC [ 2 3 ~ |
F12 | ESC [ 2 4 ~ |
Модификаторы
Alt обрабатывается префиксом последовательности с помощью escape-файла: ESC <c> , где <c> — символ, передаваемый операционной системой. Alt+Ctrl обрабатывается аналогичным образом, за исключением того, что у операционной системы будет предварительно сдвинута клавиша <c> на соответствующий управляющий символ, который будет передаваться в приложение.
Обычно передача Ctrl выполняется точно так же, как и при получении от системы. Обычно это один символ, который сдвинут вниз в зарезервированное пространство управляющего символа (0x0-0x1f). Например, ctrl+@ (0x40) становится NUL (0x00), CTRL+[ (0x5b) становится ESC (0x1b) и т. д. Несколько сочетаний клавиш CTRL обрабатываются специально в следующей таблице:
Ключ. | Sequence |
---|---|
CTRL+ПРОБЕЛ | 0x00 (NUL) |
CTRL+СТРЕЛКА ВВЕРХ | ESC [ 1; 5 A |
CTRL+СТРЕЛКА ВНИЗ | ESC [ 1; 5 B |
CTRL+СТРЕЛКА ВПРАВО | ESC [ 1; 5 C |
CTRL +СТРЕЛКА ВЛЕВО | ESC [ 1; 5 D |
Примечание.
Левый Ctrl+ правый Alt обрабатывается как AltGr. При одновременном отображении они будут удалены, а значение символа Юникода, представленного системой, будет передано в целевой объект. Система будет предварительно преобразовывать значения AltGr в соответствии с текущими входными параметрами системы.
Примеры
Пример последовательностей терминала SGR
Следующий код содержит несколько примеров форматирования текста.
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
int main()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return GetLastError();
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return GetLastError();
}
// Try some Set Graphics Rendition (SGR) terminal escape sequences
wprintf(L"\x1b[31mThis text has a red foreground using SGR.31.\r\n");
wprintf(L"\x1b[1mThis text has a bright (bold) red foreground using SGR.1 to affect the previous color setting.\r\n");
wprintf(L"\x1b[mThis text has returned to default colors using SGR.0 implicitly.\r\n");
wprintf(L"\x1b[34;46mThis text shows the foreground and background change at the same time.\r\n");
wprintf(L"\x1b[0mThis text has returned to default colors using SGR.0 explicitly.\r\n");
wprintf(L"\x1b[31;32;33;34;35;36;101;102;103;104;105;106;107mThis text attempts to apply many colors in the same command. Note the colors are applied from left to right so only the right-most option of foreground cyan (SGR.36) and background bright white (SGR.107) is effective.\r\n");
wprintf(L"\x1b[39mThis text has restored the foreground color only.\r\n");
wprintf(L"\x1b[49mThis text has restored the background color only.\r\n");
return 0;
}
Примечание.
В предыдущем примере строка '\x1b[31m
' является реализацией ESC [ <n> m с <n> 31.
На следующем рисунке показаны выходные данные предыдущего примера кода.
Пример включения обработки виртуального терминала
В следующем коде приведен пример рекомендуемого способа включения обработки виртуального терминала для приложения. Цель примера — продемонстрировать, что:
Существующий режим всегда должен извлекаться через GetConsoleMode и анализироваться, прежде чем он будет задан с помощью SetConsoleMode.
Проверка того, возвращается
0
ли SetConsoleMode и GetLastError возвращает ERROR_INVALID_PARAMETER является текущим механизмом для определения при запуске в системе нижнего уровня. Приложение, получающее ERROR_INVALID_PARAMETER с одним из более новых флагов режима консоли в битовом поле, должно корректно снизить поведение и повторить попытку.
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
int main()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return false;
}
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
if (hIn == INVALID_HANDLE_VALUE)
{
return false;
}
DWORD dwOriginalOutMode = 0;
DWORD dwOriginalInMode = 0;
if (!GetConsoleMode(hOut, &dwOriginalOutMode))
{
return false;
}
if (!GetConsoleMode(hIn, &dwOriginalInMode))
{
return false;
}
DWORD dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
DWORD dwRequestedInModes = ENABLE_VIRTUAL_TERMINAL_INPUT;
DWORD dwOutMode = dwOriginalOutMode | dwRequestedOutModes;
if (!SetConsoleMode(hOut, dwOutMode))
{
// we failed to set both modes, try to step down mode gracefully.
dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
dwOutMode = dwOriginalOutMode | dwRequestedOutModes;
if (!SetConsoleMode(hOut, dwOutMode))
{
// Failed to set any VT mode, can't do anything here.
return -1;
}
}
DWORD dwInMode = dwOriginalInMode | dwRequestedInModes;
if (!SetConsoleMode(hIn, dwInMode))
{
// Failed to set VT input mode, can't do anything here.
return -1;
}
return 0;
}
Пример выбора функций юбилейного обновления
Следующий пример представляет собой более надежный пример кода, использующий разнообразные escape-последовательности для работы с буфером, с акцентом на возможности, добавленные в юбилейном обновлении для Windows 10.
В этом примере используется альтернативный буфер экрана, выполняется управление позициями табуляции, установка полей прокрутки и изменение набора символов.
// System headers
#include <windows.h>
// Standard library C-style
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#define ESC "\x1b"
#define CSI "\x1b["
bool EnableVTMode()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return false;
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return false;
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return false;
}
return true;
}
void PrintVerticalBorder()
{
printf(ESC "(0"); // Enter Line drawing mode
printf(CSI "104;93m"); // bright yellow on bright blue
printf("x"); // in line drawing mode, \x78 -> \u2502 "Vertical Bar"
printf(CSI "0m"); // restore color
printf(ESC "(B"); // exit line drawing mode
}
void PrintHorizontalBorder(COORD const Size, bool fIsTop)
{
printf(ESC "(0"); // Enter Line drawing mode
printf(CSI "104;93m"); // Make the border bright yellow on bright blue
printf(fIsTop ? "l" : "m"); // print left corner
for (int i = 1; i < Size.X - 1; i++)
printf("q"); // in line drawing mode, \x71 -> \u2500 "HORIZONTAL SCAN LINE-5"
printf(fIsTop ? "k" : "j"); // print right corner
printf(CSI "0m");
printf(ESC "(B"); // exit line drawing mode
}
void PrintStatusLine(const char* const pszMessage, COORD const Size)
{
printf(CSI "%d;1H", Size.Y);
printf(CSI "K"); // clear the line
printf(pszMessage);
}
int __cdecl wmain(int argc, WCHAR* argv[])
{
argc; // unused
argv; // unused
//First, enable VT mode
bool fSuccess = EnableVTMode();
if (!fSuccess)
{
printf("Unable to enter VT processing mode. Quitting.\n");
return -1;
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
printf("Couldn't get the console handle. Quitting.\n");
return -1;
}
CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
GetConsoleScreenBufferInfo(hOut, &ScreenBufferInfo);
COORD Size;
Size.X = ScreenBufferInfo.srWindow.Right - ScreenBufferInfo.srWindow.Left + 1;
Size.Y = ScreenBufferInfo.srWindow.Bottom - ScreenBufferInfo.srWindow.Top + 1;
// Enter the alternate buffer
printf(CSI "?1049h");
// Clear screen, tab stops, set, stop at columns 16, 32
printf(CSI "1;1H");
printf(CSI "2J"); // Clear screen
int iNumTabStops = 4; // (0, 20, 40, width)
printf(CSI "3g"); // clear all tab stops
printf(CSI "1;20H"); // Move to column 20
printf(ESC "H"); // set a tab stop
printf(CSI "1;40H"); // Move to column 40
printf(ESC "H"); // set a tab stop
// Set scrolling margins to 3, h-2
printf(CSI "3;%dr", Size.Y - 2);
int iNumLines = Size.Y - 4;
printf(CSI "1;1H");
printf(CSI "102;30m");
printf("Windows 10 Anniversary Update - VT Example");
printf(CSI "0m");
// Print a top border - Yellow
printf(CSI "2;1H");
PrintHorizontalBorder(Size, true);
// // Print a bottom border
printf(CSI "%d;1H", Size.Y - 1);
PrintHorizontalBorder(Size, false);
wchar_t wch;
// draw columns
printf(CSI "3;1H");
int line = 0;
for (line = 0; line < iNumLines * iNumTabStops; line++)
{
PrintVerticalBorder();
if (line + 1 != iNumLines * iNumTabStops) // don't advance to next line if this is the last line
printf("\t"); // advance to next tab stop
}
PrintStatusLine("Press any key to see text printed between tab stops.", Size);
wch = _getwch();
// Fill columns with output
printf(CSI "3;1H");
for (line = 0; line < iNumLines; line++)
{
int tab = 0;
for (tab = 0; tab < iNumTabStops - 1; tab++)
{
PrintVerticalBorder();
printf("line=%d", line);
printf("\t"); // advance to next tab stop
}
PrintVerticalBorder();// print border at right side
if (line + 1 != iNumLines)
printf("\t"); // advance to next tab stop, (on the next line)
}
PrintStatusLine("Press any key to demonstrate scroll margins", Size);
wch = _getwch();
printf(CSI "3;1H");
for (line = 0; line < iNumLines * 2; line++)
{
printf(CSI "K"); // clear the line
int tab = 0;
for (tab = 0; tab < iNumTabStops - 1; tab++)
{
PrintVerticalBorder();
printf("line=%d", line);
printf("\t"); // advance to next tab stop
}
PrintVerticalBorder(); // print border at right side
if (line + 1 != iNumLines * 2)
{
printf("\n"); //Advance to next line. If we're at the bottom of the margins, the text will scroll.
printf("\r"); //return to first col in buffer
}
}
PrintStatusLine("Press any key to exit", Size);
wch = _getwch();
// Exit the alternate buffer
printf(CSI "?1049l");
}