가상 터미널 시퀀스는 출력 스트림에 쓸 때 커서 이동, 콘솔 색 및 기타 작업을 제어할 수 있는 제어 문자 시퀀스입니다. 출력 스트림 쿼리 정보 시퀀스에 대한 응답으로 또는 적절한 모드를 설정할 때 사용자 입력의 인코딩으로 입력 스트림에서 시퀀스를 수신할 수도 있습니다.
GetConsoleMode 및 SetConsoleMode 함수를 사용하여 이 동작을 구성할 수 있습니다. 가상 터미널 동작을 사용하도록 설정하는 제안된 방법의 샘플은 이 문서의 끝에 포함되어 있습니다.
다음 시퀀스의 동작은 VT100 및 파생 터미널 에뮬레이터 기술, 특히 xterm 터미널 에뮬레이터를 기반으로 합니다. 터미널 시퀀스에 대한 자세한 내용은 .에서 http://vt100.nethttp://invisible-island.net/xterm/ctlseqs/ctlseqs.html찾을 수 있습니다.
출력 시퀀스
SetConsoleMode 함수를 사용하여 화면 버퍼 핸들에 ENABLE_VIRTUAL_TERMINAL_PROCESSING 플래그가 설정된 경우 다음 터미널 시퀀스는 출력 스트림에 기록될 때 콘솔 호스트에 의해 가로채집니다. DISABLE_NEWLINE_AUTO_RETURN 플래그는 행의 마지막 열에 기록된 문자와 관련하여 다른 터미널 에뮬레이터의 커서 위치 지정 및 스크롤 동작을 에뮬레이트하는 데 유용할 수도 있습니다.
단순 커서 위치 지정
다음 설명에서 ESC는 항상 0x1B 16진수 값입니다. 터미널 시퀀스에 공백을 포함할 수 없습니다. 개별 터미널 시퀀스는 WriteFile 또는 WriteConsole 에 대한 여러 순차 호출에서 문자 또는 바이트 위치에서 분할될 수 있지만 전체 시퀀스를 한 번의 호출에 포함하는 것이 가장 좋습니다. 이러한 시퀀스를 실제로 사용하는 방법에 대한 예제는 이 항목의 끝에 있는 예제 를 참조하세요.
다음 표에서는 ESC 문자 바로 다음에 단일 작업 명령을 사용하여 간단한 이스케이프 시퀀스를 설명합니다. 이러한 시퀀스에는 매개 변수가 없으며 즉시 적용됩니다.
이 테이블의 모든 명령은 일반적으로 SetConsoleCursorPosition 콘솔 API를 호출하여 커서를 배치하는 것과 같습니다.
커서 이동은 현재 뷰포트에 의해 버퍼로 바인딩됩니다. 스크롤(사용 가능한 경우)이 발생하지 않습니다.
| 순서 | 속기 | 행동 |
|---|---|---|
| ESC M | RI | 역방향 인덱스 – \n역방향 작업을 수행하고 커서를 한 줄 위로 이동하고 가로 위치를 유지하며 필요한 경우 버퍼를 스크롤합니다.* |
| ESC 7 | DECSC | 메모리에 커서 위치 저장** |
| ESC 8 | DECSR | 메모리에서 커서 위치 복원** |
비고
* 스크롤 여백이 설정된 경우 여백 내부의 RI는 여백의 내용만 스크롤하고 뷰포트를 변경하지 않은 상태로 둡니다. (스크롤 여백 참조)
**저장 명령을 처음 사용할 때까지 메모리에 저장된 값은 없습니다. 저장된 값에 액세스하는 유일한 방법은 복원 명령을 사용하여 수행하는 것입니다.
커서 위치 지정
다음 표에는 CSI(Control Sequence Introducer) 형식 시퀀스가 포함됩니다. 모든 CSI 시퀀스는 ESC(0x1B)와 [(왼쪽 대괄호, 0x5B)로 시작하고 각 작업에 대한 자세한 정보를 지정하는 가변 길이의 매개 변수를 포함할 수 있습니다. 이 값은 약식 <n>으로 표시됩니다. 아래의 각 테이블은 기능별로 그룹화되며 각 테이블 아래에는 그룹 작동 방식을 설명하는 메모가 있습니다.
모든 매개 변수에 대해 달리 명시하지 않는 한 다음 규칙이 적용됩니다.
- <n> 은 이동할 거리를 나타내며 선택적 매개 변수입니다.
- n>이 생략되거나 0이면 <1로 처리됩니다.
- <n> 은 32,767(최대 약값)보다 클 수 없습니다.
- <n은 음수일 수 없습니다.>
이 섹션의 모든 명령은 일반적으로 SetConsoleCursorPosition 콘솔 API를 호출하는 것과 동일합니다.
커서 이동은 현재 뷰포트에 의해 버퍼로 바인딩됩니다. 스크롤(사용 가능한 경우)이 발생하지 않습니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ <n> A | CUU | 커서 위로 | 커서 위로 n <> |
| ESC [ <n> B | CUD | 커서 아래쪽 | 커서 아래로 <n> |
| ESC [ <n> C | CUF | 커서 앞으로 | 커서 앞으로(오른쪽) by <n> |
| ESC [ <n> D | 새끼 | 커서 뒤로 | 커서 뒤로(왼쪽) by <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 | 컵 | 커서 위치 | *커서가 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 시퀀스는 일반적으로 SetConsoleCursorInfo 콘솔 API를 호출하여 커서 표시 유형을 토글하는 것과 동일합니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ ? 12시간 | ATT160 | 텍스트 커서 깜박임 사용 | 커서 깜박임 시작 |
| ESC [ ? 12 l | ATT160 | 텍스트 커서 깜박임 사용 안 함 | 커서 깜박임 중지 |
| ESC [ ? 25 h | DECTCEM | 텍스트 커서 사용 모드 표시 | 커서 표시 |
| ESC [ ? 25 l | DECTCEM | 텍스트 커서 사용 모드 숨기기 | 커서 숨기기 |
팁 (조언)
사용 시퀀스는 소문자 H 문자(h)로 끝나고 사용 안 함 시퀀스는 소문자 L 문자(l)로 끝납니다.
커서 셰이프
다음 명령은 커서 셰이프를 제어하고 사용자 지정할 수 있도록 합니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| 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)가 옵니다.
뷰포트 위치 지정
이 섹션의 모든 명령은 일반적으로 ScrollConsoleScreenBuffer 콘솔 API를 호출하여 콘솔 버퍼의 콘텐츠를 이동하는 것과 같습니다.
주의 명령 이름이 잘못되었습니다. 스크롤은 뷰포트가 이동하는 방식이 아니라 작업 중에 텍스트가 이동하는 방향을 나타냅니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ <n> S | SU | 위로 스크롤 | 텍스트를 n>씩 <위로 스크롤합니다. 아래로 이동이라고도 하는 새 줄이 화면 아래쪽에서 채워짐 |
| ESC [ <n> T | SD 카드 | 아래로 스크롤 | n씩 <아래로 스크롤합니다>. 위로 이동이라고도 하며, 화면 위쪽에서 새 줄이 채워짐 |
텍스트는 커서가 있는 줄부터 이동합니다. 커서가 뷰포트의 가운데 행에 있는 경우 위로 스크롤하면 뷰포트의 아래쪽 절반을 이동하고 아래쪽에 빈 줄을 삽입합니다. 아래로 스크롤하면 뷰포트 행의 위쪽 절반을 이동하고 위쪽에 새 줄을 삽입합니다.
또한 위아래로 스크롤하면 스크롤 여백의 영향을 받는다는 점도 중요합니다. 위아래로 스크롤해도 스크롤 여백 외부의 선에는 영향을 주지 않습니다.
n>의 <기본값은 1이며, 필요에 따라 값을 생략할 수 있습니다.
텍스트 수정
이 섹션의 모든 명령은 일반적으로 FillConsoleOutputCharacter, FillConsoleOutputAttribute 및 ScrollConsoleScreenBuffer 콘솔 API를 호출하여 텍스트 버퍼 콘텐츠를 수정하는 것과 같습니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ <n> @ | ICH | 문자 삽입 | 현재 커서 위치에 n>개의 공백을 삽입<하고 모든 기존 텍스트를 오른쪽으로 이동합니다. 화면을 오른쪽으로 나가는 텍스트가 제거됩니다. |
| ESC [ <n> P | DCH | 문자 삭제 | 현재 커서 위치에서 n>자를 삭제<하고 화면 오른쪽 가장자리에서 공백 문자로 이동합니다. |
| ESC [ <n> X | ECH | 문자 지우기 | 현재 커서 위치에서 공백 문자로 덮어써 n>자를 지웁<니다. |
| ESC [ <n> L | 일리노이 주 | 줄 삽입 | <커서 위치의 버퍼에 n>줄을 삽입합니다. 커서가 켜진 선과 그 아래 선은 아래쪽으로 이동합니다. |
| ESC [ <n> M | DL | 줄 삭제 | 커서가 <있는 행부터 시작하여 버퍼에서 n> 줄을 삭제합니다. |
비고
IL 및 DL의 경우 스크롤 여백(스크롤 여백 참조)의 줄만 영향을 받습니다. 여백이 설정되지 않은 경우 기본 여백 테두리는 현재 뷰포트입니다. 줄이 여백 아래로 이동되면 삭제됩니다. 줄이 삭제되면 여백 아래쪽에 빈 줄이 삽입되고 뷰포트 외부의 선은 영향을 받지 않습니다.
각 시퀀스에 대해 생략된 경우 n>의 <기본값은 0입니다.
다음 명령의 경우 매개 변수 <n> 에는 3개의 유효한 값이 있습니다.
- 현재 커서 위치(포함)에서 줄/표시 끝까지 0 지우기
- 줄/표시의 시작 부분에서 현재 커서 위치까지 1개 지우기
- 2는 전체 줄/표시를 지웁니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ <n> J | ED | 표시에서 지우기 | n>으로 지정된 <현재 뷰포트/화면의 모든 텍스트를 공백 문자로 바꿉니다. |
| ESC [ <nK> | EL | 줄에서 지우기 | 줄의 모든 텍스트를 n>으로 지정된 <커서로 공백 문자로 바꿉니다. |
텍스트 서식 지정
이 섹션의 모든 명령은 일반적으로 SetConsoleTextAttribute 콘솔 API를 호출하여 콘솔 출력 텍스트 버퍼에 대한 모든 이후 쓰기의 서식을 조정하는 것과 같습니다.
이 명령은 아래의 <n> 위치가 세미콜론으로 구분된 0~16개의 매개 변수를 수락할 수 있다는 점입니다.
매개 변수를 지정하지 않으면 단일 0 매개 변수와 동일하게 처리됩니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ <n> m | SGR | 그래픽 변환 설정 | n으로 지정된 <대로 화면 및 텍스트의 형식 설정> |
다음 값 표는 n>에서 <다른 서식 모드를 나타내는 데 사용할 수 있습니다.
서식 모드는 왼쪽에서 오른쪽으로 적용됩니다. 경쟁 서식 옵션을 적용하면 가장 적합한 옵션이 우선적으로 적용됩니다.
색을 지정하는 옵션의 경우 색은 SetConsoleScreenBufferInfoEx API를 사용하여 수정할 수 있는 콘솔 색 테이블에 정의된 대로 사용됩니다. 테이블의 "파란색" 위치가 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 | 밝은 배경 흰색 | 배경에 굵게/밝은 흰색 적용 |
확장 색
일부 가상 터미널 에뮬레이터는 Windows 콘솔에서 제공하는 16가지 색보다 큰 색상표를 지원합니다. 이러한 확장된 색의 경우 Windows 콘솔은 표시할 기존 16가지 색 표에서 가장 가까운 적절한 색을 선택합니다. 위의 일반적인 SGR 값과 달리 확장 값은 아래 표에 따라 초기 표시기 이후 추가 매개 변수를 사용합니다.
| SGR 하위 시퀀스 | 설명 |
|---|---|
| 38 ; 2 ; <r> ; <g> ; <b> | 전경색을 r, g, <b 매개 변수에 <지정된 RGB> 값으로 설정*><> |
| 48 ; 2 ; <r> ; <g> ; <b> | r, g>, <<b> 매개 변수에 지정된 RGB 값으로>< 배경색 설정* |
| 38 ; 5 ; <s> | 88 또는 256 색 표에서 전경색을 <인> 덱스로 설정* |
| 48 ; 5 ; <s> | 88 또는 256 색 표에서 배경색 <을 인> 덱스로 설정* |
*비교를 위해 내부적으로 유지 관리되는 88 및 256 색상표는 xterm 터미널 에뮬레이터를 기반으로 합니다. 비교/반올림 테이블은 현재 수정할 수 없습니다.
화면 색
다음 명령을 사용하면 애플리케이션에서 화면 색 색상표 값을 모든 RGB 값으로 설정할 수 있습니다.
RGB 값은 16진수 값 0 과 ff슬래시 문자(예: rgb:1/24/86)로 구분되어야 합니다.
이 시퀀스는 OSC "운영 체제 명령" 시퀀스이며 나열된 다른 많은 시퀀스와 같은 CSI가 아니고 "\x1b["가 아닌 "\x1b]"로 시작합니다. OSC 시퀀스는 ()로 표시되고 전송되는 <ST>문자열 종결자로 종료됩니다ESC \0x1B 0x5C.
BEL (0x7) 대신 종결자로 사용할 수 있지만 더 긴 형식을 사용하는 것이 좋습니다.
| 순서 | 설명 | 행동 |
|---|---|---|
| ESC ] 4 ; <i> ; rgb : <r> / <g> / <b><ST> | 화면 색 수정 | 화면 색 팔레트 인덱<스 i>를 r>, g>, <<b에 지정된 RGB 값으로 <설정합니다.> |
모드 변경
입력 모드를 제어하는 시퀀스입니다. 입력 모드에는 커서 키 모드와 키패드 키 모드의 두 가지 집합이 있습니다. 커서 키 모드는 홈 및 엔드뿐만 아니라 화살표 키에서 내보내는 시퀀스를 제어하는 반면, 키패드 키 모드는 주로 numpad의 키에서 내보낸 시퀀스와 함수 키를 제어합니다.
이러한 각 모드는 간단한 부울 설정입니다. 커서 키 모드는 기본(기본값) 또는 애플리케이션이며 키패드 키 모드는 숫자(기본값) 또는 애플리케이션입니다.
이러한 모드에서 내보내는 시퀀스는 커서 키 및 Numpad 및 함수 키 섹션을 참조하세요.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC = | DECKPAM | 키패드 애플리케이션 모드 사용 | 키패드 키는 애플리케이션 모드 시퀀스를 내보낸다. |
| ESC > | DECKPNM | 키패드 숫자 모드 사용 | 키패드 키는 숫자 모드 시퀀스를 내보낸다. |
| ESC [ ? 1 h | DECCKM | 커서 키 애플리케이션 모드 사용 | 키패드 키는 애플리케이션 모드 시퀀스를 내보낸다. |
| ESC [ ? 1 l | DECCKM | 커서 키 애플리케이션 모드 사용 안 함(기본 모드 사용) | 키패드 키는 숫자 모드 시퀀스를 내보낸다. |
쿼리 상태
이 섹션의 모든 명령은 일반적으로 Get* 콘솔 API를 호출하여 현재 콘솔 버퍼 상태에 대한 상태 정보를 검색하는 것과 같습니다.
비고
이러한 쿼리는 ENABLE_VIRTUAL_TERMINAL_PROCESSING 설정된 동안 출력 스트림에서 인식된 직후 콘솔 입력 스트림으로 응답을 내보낸다. ENABLE_VIRTUAL_TERMINAL_INPUT 플래그는 쿼리를 만드는 애플리케이션이 항상 회신을 수신하려고 하는 것으로 가정하므로 쿼리 명령에는 적용되지 않습니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ 6 n | DECXCPR | 보고서 커서 위치 | 커서 위치를 다음과 같이 내보낸다: ESC [ <r> ; <c> R Where <r> = 커서 행 및 <c> = 커서 열 |
| ESC [ 0 c | 다 | 디바이스 특성 | 터미널 ID를 보고합니다. "\x1b[?1; "옵션 없는 VT101"을 나타내는 0c"입니다. |
탭
Windows 콘솔에서는 일반적으로 탭 너비가 8자일 것으로 예상하지만 특정 시퀀스를 활용하는 *nix 애플리케이션은 탭이 콘솔 창 내에 있는 위치를 조작하여 애플리케이션의 커서 이동을 최적화할 수 있습니다.
다음 시퀀스를 사용하면 애플리케이션이 콘솔 창 내에서 탭 중지 위치를 설정하고, 제거하고, 탐색할 수 있습니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC H | HTS | 가로 탭 집합 | 커서가 있는 현재 열에서 탭 정지를 설정합니다. |
| ESC [ <n> I | CHT | 커서 가로(앞으로) 탭 | 탭 정지를 사용하여 커서를 같은 행의 다음 열로 이동합니다. 탭 정지가 더 이상 없으면 행의 마지막 열로 이동합니다. 커서가 마지막 열에 있는 경우 다음 행의 첫 번째 열로 이동합니다. |
| ESC [ <n> Z | CBT | 커서 뒤로 탭 | 탭 정지를 사용하여 커서를 이전 열(같은 행)로 이동합니다. 탭 정지가 더 이상 없으면 커서를 첫 번째 열로 이동합니다. 커서가 첫 번째 열에 있으면 커서를 이동하지 않습니다. |
| ESC [ 0 g | TBC | 탭 지우기(현재 열) | 현재 열에 탭이 있으면 탭 정지를 지웁니다. 그렇지 않으면 아무 작업도 수행하지 않습니다. |
| ESC [ 3 g | TBC | 탭 지우기(모든 열) | 현재 설정된 모든 탭 정지를 지웁니다. |
- CHT 및 CBT <의 경우 n> 은 지정된 방향으로 커서를 앞으로 나아갈 횟수를 나타내는 선택적 매개 변수입니다(기본값=1).
- HTS를 통해 설정된 탭 정지가 없는 경우 CHT 및 CBT는 창의 첫 번째 열과 마지막 열을 두 개의 탭 정지로 처리합니다.
- 또한 HTS를 사용하여 탭 정지를 설정하면 콘솔이 CHT와 동일한 방식으로 TAB(0x09, '\t') 문자의 출력에서 다음 탭 정지로 이동합니다.
문자 집합 지정
다음 시퀀스를 사용하면 프로그램에서 활성 문자 집합 매핑을 변경할 수 있습니다. 이렇게 하면 프로그램에서 7비트 ASCII 문자를 내보내지만 터미널 화면 자체에 다른 문자 모양으로 표시되도록 할 수 있습니다. 현재 지원되는 문자 집합은 ASCII(기본값)와 DEC 특수 그래픽 문자 집합뿐입니다. DEC 특수 그래픽 문자 집합이 나타내는 모든 문자 목록을 참조 http://vt100.net/docs/vt220-rm/table2-4.html 하세요.
| 순서 | 설명 | 행동 |
|---|---|---|
| ESC ( 0 | 문자 집합 지정 – DEC 선 그리기 | DEC 선 그리기 모드 사용 |
| ESC( B | 문자 집합 지정 – US ASCII | ASCII 모드 사용(기본값) |
특히 DEC 선 그리기 모드는 콘솔 애플리케이션에서 테두리를 그리는 데 사용됩니다. 다음 표에서는 ASCII 문자가 어떤 선 그리기 문자에 매핑되는지 보여줍니다.
| 16진수 | 아스키 | DEC 선 그리기 |
|---|---|---|
| 0x6a | j | ┘ |
| 0x6b | k | ┐ |
| 0x6c | l | ┌ |
| 0x6d | m | └ |
| 0x6e | n | ┼ |
| 0x71 | q | ─ |
| 0x74 | t | ├ |
| 0x75 | u | ┤ |
| 0x76 | v | ┴ |
| 0x77 | w | ┬ |
| 0x78 | x | │ |
스크롤 여백
다음 시퀀스를 사용하면 프로그램에서 스크롤 작업의 영향을 받는 화면의 "스크롤 영역"을 구성할 수 있습니다. 화면이 '\n' 또는 RI와 같이 스크롤할 때 조정되는 행의 하위 집합입니다. 이러한 여백은 IL(줄 삽입) 및 DL(줄 삭제), SU(위로 스크롤) 및 스크롤 아래로 스크롤(SD)으로 수정된 행에도 영향을 줍니다.
스크롤 여백은 화면의 나머지 부분이 채워질 때 스크롤되지 않는 부분(예: 위쪽에 제목 표시줄이 있거나 애플리케이션 아래쪽에 상태 표시줄이 있는 경우)에 특히 유용할 수 있습니다.
DECSTBM의 경우 두 개의 선택적 매개 변수인 <t> 와 <b>가 있으며, 이 매개 변수는 스크롤 영역의 위쪽 및 아래쪽 줄을 나타내는 행을 지정하는 데 사용됩니다( 포함). 매개 변수를 생략 <하면 t> 는 기본값이 1이고 <b> 는 현재 뷰포트 높이로 기본값이 지정됩니다.
스크롤 여백은 버퍼당이므로 대체 버퍼와 주 버퍼는 별도의 스크롤 여백 설정을 유지 관리하므로 대체 버퍼의 전체 화면 애플리케이션은 주 버퍼의 여백을 포이즌하지 않습니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ <t> ; <b> r | DECSTBM | 스크롤 영역 설정 | 뷰포트의 VT 스크롤 여백을 설정합니다. |
창 제목
다음 명령을 사용하면 애플리케이션이 콘솔 창의 제목을 지정된 <문자열> 매개 변수로 설정할 수 있습니다. 문자열을 허용하려면 255자 미만이어야 합니다. 이는 지정된 문자열을 사용하여 SetConsoleTitle을 호출하는 것과 같습니다.
이러한 시퀀스는 OSC "운영 체제 명령" 시퀀스이며 나열된 다른 많은 시퀀스와 같은 CSI가 아니고 "\x1b["가 아닌 "\x1b]"로 시작됩니다. OSC 시퀀스는 ()로 표시되고 전송되는 <ST>문자열 종결자로 종료됩니다ESC \0x1B 0x5C.
BEL (0x7) 대신 종결자로 사용할 수 있지만 더 긴 형식을 사용하는 것이 좋습니다.
| 순서 | 설명 | 행동 |
|---|---|---|
| ESC ] 0 ; <문자열><세인트> | 창 제목 설정 | 콘솔 창의 제목을 문자열>로 <설정합니다. |
| ESC ] 2 ; <문자열><세인트> | 창 제목 설정 | 콘솔 창의 제목을 문자열>로 <설정합니다. |
여기서 종료되는 문자는 "Bell" 문자 '\x07'입니다.
대체 화면 버퍼
*Nix 스타일 애플리케이션은 종종 대체 화면 버퍼를 활용하므로 버퍼를 시작한 애플리케이션에 영향을 주지 않고 버퍼의 전체 콘텐츠를 수정할 수 있습니다. 대체 버퍼는 스크롤백 영역이 없는 창의 크기입니다.
이 동작의 예는 bash에서 vim이 시작되는 시기를 고려합니다. Vim은 화면 전체를 사용하여 파일을 편집한 다음 bash로 돌아가면 원래 버퍼가 변경되지 않은 상태로 유지됩니다.
| 순서 | 설명 | 행동 |
|---|---|---|
| ESC [ ? 1 0 4 9 h | 대체 화면 버퍼 사용 | 새 대체 화면 버퍼로 전환합니다. |
| ESC [ ? 1 0 4 9 l | 기본 화면 버퍼 사용 | 주 버퍼로 전환합니다. |
창 너비
다음 시퀀스를 사용하여 콘솔 창의 너비를 제어할 수 있습니다. 이는 SetConsoleScreenBufferInfoEx 콘솔 API를 호출하여 창 너비를 설정하는 것과 거의 동일합니다.
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ ? 3 h | DECCOLM | 열 수를 132로 설정 | 콘솔 너비를 너비가 132열로 설정합니다. |
| ESC [ ? 3 l | DECCOLM | 열 수를 80으로 설정 | 콘솔 너비를 80열 너비로 설정합니다. |
일시 초기화
다음 시퀀스를 사용하여 특정 속성을 기본값으로 다시 설정할 수 있습니다. 다음 속성은 다음 기본값으로 다시 설정됩니다(이러한 속성을 제어하는 시퀀스도 나열됨).
- 커서 표시 유형: 표시(DECTEM)
- 숫자 키패드: 숫자 모드(DECNKM)
- 커서 키 모드: 기본 모드(DECCKM)
- 위쪽 및 아래쪽 여백: 위쪽=1, 아래쪽=콘솔 높이(DECSTBM)
- 문자 집합: US ASCII
- 그래픽 변환: 기본/해제(SGR)
- 커서 상태 저장: 홈 위치(0,0)(DECSC)
| 순서 | 코드 | 설명 | 행동 |
|---|---|---|---|
| ESC [ ! p | DECSTR | 일시 초기화 | 특정 터미널 설정을 기본값으로 다시 설정합니다. |
입력 시퀀스
SetConsoleMode 플래그를 사용하여 입력 버퍼 핸들에 ENABLE_VIRTUAL_TERMINAL_INPUT 플래그가 설정된 경우 입력 스트림의 콘솔 호스트에서 다음 터미널 시퀀스를 내보냅니다.
지정된 입력 키에 대해 내보낸 시퀀스를 제어하는 두 가지 내부 모드, 커서 키 모드 및 키패드 키 모드가 있습니다. 이러한 내용은 모드 변경 섹션에 설명되어 있습니다.
커서 키
| 열쇠 | 표준 모드 | 애플리케이션 모드 |
|---|---|---|
| 위쪽 화살표 | ESC [ A | ESC O A |
| 아래쪽 화살표 | ESC [ B | ESC O B |
| 오른쪽 화살표 | ESC [ C | ESC O C |
| 왼쪽 화살표 | ESC [ D | ESC O D |
| 집 | 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 |
Numpad 및 함수 키
| 열쇠 | 순서 |
|---|---|
| 백스페이스 | 0x7f(DEL) |
| 일시 중지 | 0x1a(SUB) |
| 탈출 | 0x1b(ESC) |
| 삽입 | ESC [ 2 ~ |
| 삭제 | ESC [ 3 ~ |
| 페이지 위로 | ESC [ 5 ~ |
| 페이지 아래로 이동 | ESC [ 6 ~ |
| F1 레이싱 | ESC O P |
| F2 (키보드 기능 키 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는 시퀀스에 이스케이프 접두사를 추가하여 처리됩니다. 여기서 c>는 운영 체제에서 전달하는 문자인 ESC <c><입니다. Alt+Ctrl은 운영 체제에서 c> 키를 애플리케이션에 릴레이할 적절한 컨트롤 문자로 미리 이동한다는 <점을 제외하고 동일한 방식으로 처리됩니다.
Ctrl은 일반적으로 시스템에서 받은 것과 정확하게 전달됩니다. 일반적으로 컨트롤 문자 예약된 공간(0x0-0x1f)으로 아래로 이동되는 단일 문자입니다. 예를 들어 Ctrl+@(0x40)는 NUL(0x00),Ctrl+[(0x5b)는 ESC(0x1b) 등이 됩니다. 다음 표에 따라 몇 가지 Ctrl 키 조합이 특별히 처리됩니다.
| 열쇠 | 순서 |
|---|---|
| Ctrl+공백 | NUL(0x00) |
| 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'은 n이 31인 ESC [ <n> m<> 의 구현입니다.
다음 그래픽은 이전 코드 예제의 출력을 보여줍니다.
가상 터미널 처리 사용 예제
다음 코드는 애플리케이션에 대한 가상 터미널 처리를 사용하도록 설정하는 권장 방법의 예를 제공합니다. 샘플의 의도는 다음을 보여 주는 것입니다.
기존 모드는 항상 GetConsoleMode를 통해 검색되고 SetConsoleMode로 설정되기 전에 분석해야 합니다.
SetConsoleMode가 반환되고 GetLastError가 ERROR_INVALID_PARAMETER 반환
0하는지 여부를 확인하는 것은 하위 수준 시스템에서 실행할 때 확인하는 현재 메커니즘입니다. 비트 필드에서 최신 콘솔 모드 플래그 중 하나를 사용하여 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;
}
1주년 업데이트 기능 선택 예제
다음 예제는 다양한 이스케이프 시퀀스를 사용하여 버퍼를 조작하는 보다 강력한 코드 예제로, Windows 10 1주년 업데이트에 추가된 기능에 중점을 둡니다.
다음은 대체 화면 버퍼를 사용하고, 탭 정지를 조작하고, 스크롤 여백을 설정하고, 문자 집합을 변경하는 예제입니다.
// 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");
}