Udostępnij przez


Sekwencje konsoli wirtualnego terminala

Wirtualne sekwencje terminali to sekwencje znaków sterowania, które mogą kontrolować ruch kursora, kolor konsoli i inne operacje podczas zapisywania do strumienia wyjściowego. Sekwencje mogą być również odbierane na strumieniu wejściowym w odpowiedzi na sekwencję informacji o kwerendzie strumienia wyjściowego lub jako kodowanie danych wejściowych użytkownika po ustawieniu odpowiedniego trybu.

Aby skonfigurować to zachowanie, można użyć funkcji GetConsoleMode i SetConsoleMode . Na końcu tego dokumentu znajduje się przykład sugerowanego sposobu włączania zachowań terminali wirtualnych.

Zachowanie poniższych sekwencji opiera się na technologiach emulatora terminalu VT100 i pochodnych, a w szczególności na emulatorze terminalu xterm. Więcej informacji o sekwencjach terminali można znaleźć na stronie i pod http://vt100.net adresem http://invisible-island.net/xterm/ctlseqs/ctlseqs.html.

Sekwencje wyjściowe

Następujące sekwencje terminalu są przechwytywane przez hosta konsoli podczas zapisywania w strumieniu wyjściowym, jeśli flaga ENABLE_VIRTUAL_TERMINAL_PROCESSING jest ustawiona na uchwyt buforu ekranu przy użyciu funkcji SetConsoleMode . Należy pamiętać, że flaga DISABLE_NEWLINE_AUTO_RETURN może być również przydatna w emulowaniu położenia kursora i przewijaniu innych emulatorów terminalu w odniesieniu do znaków zapisanych w końcowej kolumnie w dowolnym wierszu.

Proste pozycjonowanie kursora

We wszystkich poniższych opisach esc to zawsze wartość szesnastkowa 0x1B. Nie należy uwzględniać spacji w sekwencjach terminali. Poszczególne sekwencje terminalowe można podzielić na dowolny znak lub pozycję bajtów w wielu sekwencyjnych wywołaniach metody WriteFile lub WriteConsole , ale najlepszym rozwiązaniem jest uwzględnienie całej sekwencji w jednym wywołaniu. Przykład użycia tych sekwencji w praktyce można znaleźć w przykładzie na końcu tego tematu.

W poniższej tabeli opisano proste sekwencje ucieczki za pomocą pojedynczego polecenia akcji bezpośrednio po znaku ESC. Te sekwencje nie mają żadnych parametrów i natychmiast zastosować je.

Wszystkie polecenia w tej tabeli są zwykle równoważne wywołaniu interfejsu API konsoli SetConsoleCursorPosition , aby umieścić kursor.

Ruch kursora zostanie ograniczony przez bieżące wyeksportuj do buforu. Przewijanie (jeśli jest dostępne) nie zostanie wykonane.

Kolejność Stenografia Zachowanie
ESC M wystąpienie zarezerwowane Indeks odwrotny — wykonuje operację odwrotną \n, przenosi kursor w górę o jedną linię, utrzymuje położenie w poziomie, przewija bufor w razie potrzeby*
ESC 7 DECSC Zapisz położenie kursora w pamięci**
ESC 8 DECSR Przywróć położenie kursora z pamięci**

Uwaga / Notatka

* Jeśli istnieją ustawione marginesy przewijania, wystąpienia zarezerwowane wewnątrz marginesów będą przewijać tylko zawartość marginesów i pozostawić widokport bez zmian. (Zobacz Przewijanie marginesów)

**Nie będzie żadnej wartości zapisanej w pamięci do momentu pierwszego użycia polecenia zapisywania. Jedynym sposobem uzyskania dostępu do zapisanej wartości jest polecenie restore.

Pozycjonowanie kursora

Poniższe tabele obejmują sekwencje typów Control Sequence Introducer (CSI). Wszystkie sekwencje CSI zaczynają się od esc (0x1B), a następnie [ (lewy nawias, 0x5B) i mogą zawierać parametry zmiennej długości, aby określić więcej informacji dla każdej operacji. Będzie to reprezentowane przez skrót <n>. Każda poniższa tabela jest pogrupowana według funkcji z notatkami poniżej każdej tabeli wyjaśniającej, jak działa grupa.

Dla wszystkich parametrów obowiązują następujące reguły, chyba że określono inaczej:

  • <n> reprezentuje odległość do przeniesienia i jest opcjonalnym parametrem
  • Jeśli <n> zostanie pominięty lub równy 0, będzie traktowany jako 1
  • <n> nie może być większe niż 32 767 (maksymalna krótka wartość)
  • <n> nie może być ujemna

Wszystkie polecenia w tej sekcji są zwykle równoważne wywołaniu interfejsu API konsoli SetConsoleCursorPosition .

Ruch kursora zostanie ograniczony przez bieżące wyeksportuj do buforu. Przewijanie (jeśli jest dostępne) nie zostanie wykonane.

Kolejność Code Opis Zachowanie
ESC [ <n> A CUU Kursor w górę Kursor w górę o <n>
ESC [ <n> B CUD Kursor w dół Kursor w dół o <n>
ESC [ <n> C CUF Kursor do przodu Kursor do przodu (w prawo) przez <n>
ESC [ <n> D CUB Kursor do tyłu Kursor do tyłu (w lewo) według <n>
ESC [ <n> E CNL Następny wiersz kursora Kursor w dół <n> wierszy z bieżącej pozycji
ESC [ <n> F CPL Poprzedni wiersz kursora Umieść kursor w górę <n> wierszy z bieżącej pozycji
ESC [ <n> G CHA Kursor w poziomie bezwzględnym Kursor przenosi się do <n>pozycji poziomej w bieżącym wierszu
ESC [ <n> d VPA Położenie pionowej linii bezwzględnej Kursor jest przesuwany w <pionie do n>pozycji w bieżącej kolumnie
ESC [ <y> ; <x> H FILIŻANKA Położenie kursora *Kursor przenosi się do <x>; <współrzędna y> w widoku, gdzie <x> jest kolumną <wiersza y>
ESC [ <y> ; <x> f HVP Położenie w pionie w poziomie *Kursor przenosi się do <x>; <współrzędna y> w widoku, gdzie <x> jest kolumną <wiersza y>
ESC [ s ANSISYSSC Zapisz kursor — emulacja Ansi.sys **Bez parametrów wykonuje operację zapisywania kursora, na przykład DECSC
ESC [ u ANSISYSRC Przywracanie kursora — emulacja Ansi.sys **Bez parametrów wykonuje operację kursora przywracania, na przykład DECRC

Uwaga / Notatka

*<Parametry x> i <y> mają takie same ograniczenia jak <n> powyżej. Jeśli <wartości x> i <y> zostaną pominięte, zostaną ustawione na 1;1.

**ANSI.sys dokumentację historyczną można znaleźć pod https://msdn.microsoft.com/library/cc722862.aspx adresem i jest zaimplementowana w celu zapewnienia wygody/zgodności.

Widoczność kursora

Następujące polecenia kontrolują widoczność kursora i jego stan. Sekwencje DECTCEM są zwykle równoważne wywołaniu interfejsu API konsoli SetConsoleCursorInfo , aby przełączyć widoczność kursora.

Kolejność Code Opis Zachowanie
ESC [ ? 12 h ATT160 Kursor tekstu włącz Uruchamianie kursora
ESC [ ? 12 l ATT160 Kursor tekstu wyłącza Zatrzymaj kursora
ESC [ ? 25 h DECTCEM Pokaż tryb włączania kursora tekstu Pokaż kursor
ESC [ ? 25 l DECTCEM Tryb włączania kursora tekstu — ukryj Ukryj kursor

Wskazówka

Sekwencje włączania kończą się małymi literami H (h) i wyłączają sekwencje kończą się małymi literami L (l).

Kształt kursora

Następujące polecenia kontrolują i umożliwiają dostosowanie kształtu kursora.

Kolejność Code Opis Zachowanie
ESC [ 0 SP q DECSCUSR Kształt użytkownika Domyślny kształt kursora skonfigurowany przez użytkownika
ESC [ 1 SP q DECSCUSR Blok kształt kursora blokowego
ESC [ 2 SP q DECSCUSR Stały blok Stały kształt kursora blokowego
ESC [ 3 SP q DECSCUSR Podkreślenie podkreślenie kształtu kursora
ESC [ 4 SP q DECSCUSR Stałe podkreślnie Stały kształt kursora podkreślonych
ESC [ 5 SP q DECSCUSR Pasek kształt kursora słupka
ESC [ 6 SP q DECSCUSR Słupek stały Stały kształt kursora słupka

Uwaga / Notatka

SP jest znakiem spacji literału (0x20) w pozycji pośredniej i następuje q (0x71) w końcowej pozycji.

Pozycjonowanie widoku

Wszystkie polecenia w tej sekcji są zwykle równoważne wywołaniu interfejsu API konsoli ScrollConsoleScreenBuffer w celu przeniesienia zawartości buforu konsoli.

Ostrożność Nazwy poleceń są mylące. Przewijanie odwołuje się do kierunku, w którym tekst jest przesuwany podczas operacji, a nie do tego, w jaki sposób widokport wydaje się przenosić.

Kolejność Code Opis Zachowanie
ESC [ <n> S SU Przewiń w górę Przewiń tekst w górę o <n>. Znane również jako przesuwanie w dół, nowe linie wypełniają się od dołu ekranu
ESC [ <n> T SD Przewiń w dół Przewiń w dół o <n>. Znane również jako przesuwanie w górę, nowe linie wypełniają się od góry ekranu

Tekst jest przenoszony od wiersza, na który znajduje się kursor. Jeśli kursor znajduje się w środkowym wierszu okna widoku, przewiń w górę spowoduje przeniesienie dolnej połowy okna widoku i wstawienie pustych wierszy u dołu. Przewinięcie w dół spowoduje przeniesienie górnej połowy wierszy widoku i wstawienie nowych wierszy u góry.

Należy również pamiętać, że przewijanie w górę i w dół również wpływa na marginesy przewijania. Przewijanie w górę i w dół nie wpłynie na żadne wiersze poza marginesami przewijania.

Wartość domyślna n <> to 1, a wartość można opcjonalnie pominąć.

Modyfikacja tekstu

Wszystkie polecenia w tej sekcji są zwykle równoważne wywołaniu interfejsów API konsoli FillConsoleOutputCharacter, FillConsoleOutputAttribute i ScrollConsoleScreenBuffer w celu zmodyfikowania zawartości buforu tekstu.

Kolejność Code Opis Zachowanie
ESC [ <n> @ ICH Wstaw znak Wstaw <n> spacji na bieżącej pozycji kursora, przesuwając cały istniejący tekst po prawej stronie. Tekst zamykający ekran po prawej stronie jest usuwany.
ESC [ <n> P DCH Usuń znak Usuń <n> znaków na bieżącym położeniu kursora, przesuwając znaki spacji z prawej krawędzi ekranu.
ESC [ <n> X ECH Wymazywanie znaku Wymaż <n> znaków z bieżącego położenia kursora, zastępując je znakiem spacji.
ESC [ <n> L IL Wstaw wiersz Wstawia n> wierszy <do buforu na pozycji kursora. Linia, na która znajduje się kursor, a pod nim linie zostaną przesunięte w dół.
ESC [ <n> M DL Usuń wiersz Usuwa n> wierszy <z buforu, zaczynając od wiersza, na który znajduje się kursor.

Uwaga / Notatka

W przypadku il i DL mają wpływ tylko linie na marginesach przewijania (zobacz Marginesy przewijania). Jeśli nie ustawiono żadnych marginesów, domyślne obramowania marginesu to bieżące okienko widoku. Jeśli wiersze zostaną przesunięte poniżej marginesów, zostaną one odrzucone. Gdy wiersze są usuwane, puste wiersze są wstawiane w dolnej części marginesów, linie spoza okienka widoku nigdy nie mają wpływu.

Dla każdej z sekwencji wartość domyślna n<>, jeśli zostanie pominięta, to 0.

W przypadku następujących poleceń parametr <n> ma 3 prawidłowe wartości:

  • 0 wymazuje się z bieżącego położenia kursora (włącznie) na końcu wiersza/wyświetlania
  • 1 wymazuje się z początku wiersza/wyświetlania do i uwzględnia bieżące położenie kursora
  • 2 usuwa cały wiersz/wyświetlacz
Kolejność Code Opis Zachowanie
ESC [ <n> J ED Wymazywanie w wyświetlaczu Zastąp cały tekst w bieżącym widoku/ekranie określonym przez <n> znakami spacji
ESC [ <n> K EL Wymazywanie w wierszu Zastąp cały tekst w wierszu kursorem określonym przez <n> znakami spacji

Formatowanie tekstu

Wszystkie polecenia w tej sekcji są zwykle równoważne wywołaniu interfejsów API konsoli SetConsoleTextAttribute w celu dostosowania formatowania wszystkich przyszłych zapisów do buforu tekstu wyjściowego konsoli.

To polecenie jest specjalne, ponieważ <n> pozycji poniżej może zaakceptować od 0 do 16 parametrów oddzielonych średnikami.

Jeśli nie określono parametrów, jest traktowany tak samo jak jeden parametr 0.

Kolejność Code Opis Zachowanie
ESC [ <n> m SGR Ustawianie odwzorowania grafiki Ustawianie formatu ekranu i tekstu określonego przez <n>

Poniższa tabela wartości może służyć w <n> do reprezentowania różnych trybów formatowania.

Tryby formatowania są stosowane od lewej do prawej. Zastosowanie konkurencyjnych opcji formatowania spowoduje, że pierwszeństwo będzie miało najbardziej odpowiednia opcja.

W przypadku opcji określających kolory kolory będą używane zgodnie z definicją w tabeli kolorów konsoli, które można modyfikować przy użyciu interfejsu API SetConsoleScreenBufferInfoEx . Jeśli tabela zostanie zmodyfikowana tak, aby pozycja "niebieska" w tabeli wyświetlała odcień RGB na czerwono, wszystkie wywołania elementu Foreground Blue będą wyświetlać ten czerwony kolor do momentu zmiany w inny sposób.

Wartość Opis Zachowanie
0 Wartość domyślna Zwraca wszystkie atrybuty do stanu domyślnego przed modyfikacją
1 Pogrubienie/jasne Stosuje flagę jasności/intensywności do koloru pierwszego planu
22 Bez pogrubienia/jasnego Usuwa flagę jasności/intensywności z koloru pierwszego planu
4 Podkreślenie Dodaje podkreślnie
24 Brak podkreślonia Usuwa podkreślnie
7 Negatywna Zamienia kolory pierwszego planu i tła
27 Dodatnie (bez ujemnych) Zwraca tło/pierwszego planu do normalnego
30 Pierwszy plan Stosuje kolor niegrubiony/jasny na pierwszym planie
31 Pierwszy plan czerwony Stosuje niegrubioną/jasnoczerwone do pierwszego planu
32 Pierwszy plan zielony Stosuje niegrubioną/jasnozieloną do pierwszego planu
33 Pierwszy plan żółty Stosuje niegrubioną/jasnożółtą do pierwszego planu
34 Pierwszy plan — niebieski Stosuje niegrubioną/jasnoniebieską do pierwszego planu
35 Pierwszy plan magenta Stosuje bez pogrubienia/jasnego magenta na pierwszym planie
36 Pierwszy plan Cyan Stosuje niegrubiony/jasny cyjan na pierwszym planie
37 Pierwszy plan biały Stosuje kolor inny niż pogrubiony/jasny biały na pierwszym planie
38 Rozszerzone pierwszego planu Stosuje rozszerzoną wartość koloru do pierwszego planu (zobacz szczegóły poniżej)
39 Ustawienie domyślne pierwszego planu Stosuje tylko pierwszą część wartości domyślnych (patrz 0)
40 Tło czarne Stosuje kolor niegrubiony/jasny do tła
41 Tło czerwone Stosuje kolor niegrubiony/jasnoczerwony do tła
42 Tło zielone Stosuje niegrubioną/jasnozieloną do tła
43 Tło żółte Stosuje niegrubioną/jasnożółtą do tła
44 Tło niebieskie Stosuje niegrubioną/jasnoniebieską do tła
45 Tło Magenta Stosuje bez pogrubienia/jasnej magenty do tła
46 Tło Cyan Stosuje niegrubiony/jasny cyjan do tła
47 Tło białe Stosuje kolor inny niż pogrubiony/jasny biały do tła
48 Rozszerzone tło Stosuje rozszerzoną wartość koloru do tła (zobacz szczegóły poniżej)
49 Ustawienie domyślne tła Stosuje tylko część tła wartości domyślnych (patrz 0)
90 Jasny pierwszy plan Stosuje pogrubienie/jasnoczerń do pierwszego planu
91 Jasny pierwszy plan czerwony Stosuje pogrubienie/jasnoczerwony na pierwszym planie
92 Jasny pierwszy plan zielony Stosuje pogrubienie/jasnozielony do pierwszego planu
93 Jasny pierwszy plan żółty Stosuje pogrubienie/jasnożółte do pierwszego planu
94 Jasny pierwszy plan niebieski Stosuje pogrubienie/jasnoniebieski do pierwszego planu
95 Bright Foreground Magenta Stosuje pogrubienie/jasne magenta na pierwszym planie
96 Bright Foreground Cyan Stosuje pogrubienie/jasny cyjan na pierwszym planie
97 Jasny pierwszy plan biały Stosuje pogrubienie/jasny biały na pierwszym planie
100 Jasne tło — Stosuje pogrubienie/jasnoczerń do tła
101 Jasne tło czerwone Stosuje pogrubienie/jasnoczerwone do tła
102 Jasne tło zielone Stosuje pogrubienie/jasnozielony do tła
103 Jasne tło żółte Stosuje pogrubienie/jasnożółte do tła
104 Jasnoniebieskie tło Stosuje pogrubienie/jasnoniebieski do tła
105 Jasne tło magenta Stosuje pogrubienie/jasne magenta do tła
106 Jasne tło Cyan Stosuje pogrubienie/jasny cyjan do tła
107 Jasne tło białe Stosuje pogrubienie/jasny biały do tła

Kolory rozszerzone

Niektóre emulatory terminali wirtualnych obsługują paletę kolorów większych niż 16 kolorów dostarczonych przez konsolę systemu Windows. W przypadku tych kolorów rozszerzonych konsola systemu Windows wybierze najbliższy odpowiedni kolor z istniejącej tabeli kolorów 16 do wyświetlenia. W przeciwieństwie do typowych wartości SGR powyżej wartości rozszerzone będą zużywać dodatkowe parametry po początkowym wskaźniku zgodnie z poniższą tabelą.

Podsekwencja SGR Opis
38 ; 2 ; <r> ; <g> ; <b> Ustaw kolor pierwszego planu na wartość RGB określoną w <r>, <g>, <b> parameters*
48 ; 2 ; <r> ; <g> ; <b> Ustaw kolor tła na wartość RGB określoną w <r>, <g>, <b> parameters*
38 ; 5 ; <s> Ustaw kolor pierwszego planu na <> indeks w tabeli kolorów 88 lub 256*
48 ; 5 ; <s> Ustaw kolor tła na <> indeks w tabeli kolorów 88 lub 256*

*Palety kolorów 88 i 256 obsługiwane wewnętrznie na potrzeby porównania są oparte na emulatorze terminalu xterm. Obecnie nie można modyfikować tabel porównania/zaokrąglania.

Kolory ekranu

Następujące polecenie umożliwia aplikacji ustawienie wartości palety kolorów ekranu na dowolną wartość RGB.

Wartości RGB powinny być wartościami szesnastkowymi między 0 i ff, a oddzielone znakiem ukośnika do przodu (np. rgb:1/24/86).

Należy pamiętać, że ta sekwencja to sekwencja OSC "Polecenie systemu operacyjnego", a nie CSI, taka jak wiele innych wymienionych sekwencji, a w związku z tym zaczyna się od "\x1b]", a nie "\x1b[". Jako sekwencje OSC są one zakończone terminatorem ciągu reprezentowanym jako <ST> i przesyłane za ESC \ pomocą (0x1B 0x5C). BEL (0x7) może być używany zamiast tego jako terminator, ale preferowana jest dłuższa forma.

Kolejność Opis Zachowanie
ESC ] 4 ; <i> ; rgb: <r> / <g> / <b><ST> Modyfikowanie kolorów ekranu Ustawia indeks <palety kolorów ekranu i> na wartości RGB określone w <r>, <g>, <b>

Zmiany trybu

Są to sekwencje sterujące trybami wprowadzania. Istnieją dwa różne zestawy trybów wprowadzania, Tryb kursora i Tryb klawiatury. Tryb kursora kontroluje sekwencje emitowane przez strzałek, a także Home and End, podczas gdy tryb klawiatury kontroluje sekwencje emitowane przez klucze na numpad przede wszystkim, a także klucze funkcji.

Każdy z tych trybów jest prostymi ustawieniami logicznymi — tryb kursora jest normalny (domyślny) lub aplikacja, a tryb kluczy klawiatury jest numeryczny (domyślny) lub Aplikacja.

Zobacz sekcje kursora i funkcji Numpad i Function, aby zapoznać się z sekwencjami emitowanych w tych trybach.

Kolejność Code Opis Zachowanie
ESC = DECKPAM Włączanie trybu aplikacji klawiatury Klucze klawiatury będą emitować sekwencje trybu aplikacji.
ESC > DECKPNM Włączanie trybu numerycznego klawiatury Klucze klawiatury emitują sekwencje trybu liczbowego.
ESC [ ? 1 godz. DECCKM Włącz tryb aplikacji kursora Klucze klawiatury będą emitować sekwencje trybu aplikacji.
ESC [ ? 1 l DECCKM Wyłącz tryb aplikacji kursora (użyj trybu normalnego) Klucze klawiatury emitują sekwencje trybu liczbowego.

Stan zapytania

Wszystkie polecenia w tej sekcji są zwykle równoważne wywołaniu interfejsów API konsoli Get* w celu pobrania informacji o stanie bieżącego stanu buforu konsoli.

Uwaga / Notatka

Te zapytania będą emitować odpowiedzi do strumienia wejściowego konsoli natychmiast po rozpoznaniu na strumieniu wyjściowym podczas ustawiania ENABLE_VIRTUAL_TERMINAL_PROCESSING. Flaga ENABLE_VIRTUAL_TERMINAL_INPUT nie ma zastosowania do poleceń zapytania, ponieważ zakłada się, że aplikacja tworząca zapytanie zawsze będzie chciała otrzymać odpowiedź.

Kolejność Code Opis Zachowanie
ESC [ 6 n DECXCPR Położenie kursora raportu Emituj położenie kursora jako: ESC [ <r> ; <c> R Where <r> = wiersz kursora i <c> = kolumna kursora
ESC [ 0 c DA Atrybuty urządzenia Zgłoś tożsamość terminalu. Czy emituje "\x1b[?1; 0c", wskazując "VT101 bez opcji".

Karty

Chociaż konsola systemu Windows tradycyjnie oczekuje, że karty będą mieć wyłącznie osiem znaków szerokości, *aplikacje nix korzystające z niektórych sekwencji mogą manipulować, gdzie tabulatory znajdują się w oknach konsoli, aby zoptymalizować ruch kursora przez aplikację.

Następujące sekwencje umożliwiają aplikacji ustawianie lokalizacji zatrzymania tabulatora w oknie konsoli, usuwanie ich i nawigowanie między nimi.

Kolejność Code Opis Zachowanie
ESC H HTS Zestaw kart poziomych Ustawia zatrzymanie karty w bieżącej kolumnie, w których znajduje się kursor.
ESC [ <n> I CHT Karta Kursor w poziomie (do przodu) Przesuń kursor do następnej kolumny (w tym samym wierszu) z zatrzymaniem karty. Jeśli nie ma więcej zatrzymań karty, przejdź do ostatniej kolumny w wierszu. Jeśli kursor znajduje się w ostatniej kolumnie, przejdź do pierwszej kolumny następnego wiersza.
ESC [ <n> Z CBT Karta Kursor do tyłu Przenieś kursor do poprzedniej kolumny (w tym samym wierszu) z zatrzymaniem karty. Jeśli nie ma więcej zatrzymań karty, przenosi kursor do pierwszej kolumny. Jeśli kursor znajduje się w pierwszej kolumnie, nie przenosi kursora.
ESC [ 0 g TBC Wyczyść kartę (bieżąca kolumna) Czyści tabulator w bieżącej kolumnie, jeśli istnieje. W przeciwnym razie nic nie robi.
ESC [ 3 g TBC Wyczyść kartę (wszystkie kolumny) Czyści wszystkie aktualnie ustawione tabulatory.
  • W przypadku zarówno CHT, jak i CBT n> jest opcjonalnym parametrem wskazującym, <ile razy należy przejść kursor w określonym kierunku.
  • Jeśli nie ma żadnych zatrzymań tabulatorów ustawionych za pośrednictwem HTS, CHT i CBT będą traktować pierwsze i ostatnie kolumny okna jako jedyną kartę zatrzymuje się.
  • Użycie funkcji HTS do ustawienia zatrzymania karty spowoduje również przejście konsoli do następnego zatrzymania karty na danych wyjściowych tabulatora (0x09, '\t'), w taki sam sposób jak CHT.

Wyznaczanie zestawu znaków

Następujące sekwencje umożliwiają programowi zmianę mapowania aktywnego zestawu znaków. Dzięki temu program może emitować 7-bitowe znaki ASCII, ale wyświetlać je jako inne glify na samym ekranie terminalu. Obecnie jedynymi obsługiwanymi zestawami znaków są ASCII (ustawienie domyślne) i zestaw znaków specjalnych DEC. Zobacz http://vt100.net/docs/vt220-rm/table2-4.html listę wszystkich znaków reprezentowanych przez zestaw znaków specjalnych DEC.

Kolejność Opis Zachowanie
ESC ( 0 Wyznaczanie zestawu znaków — rysunek linii DEC Włącza tryb rysowania wierszy DEC
ESC ( B Wyznaczanie zestawu znaków — US ASCII Włącza tryb ASCII (ustawienie domyślne)

W szczególności tryb rysunku liniowego DEC jest używany do rysowania obramowań w aplikacjach konsoli. W poniższej tabeli przedstawiono, co znak ASCII mapuje na jaki znak rysunku wiersza.

Hex ASCII Rysunek linii DEC
0x6a j
0x6b k
0x6c l
0x6d m
0x6e n
0x71 q
0x74 t
0x75 u
0x76 v
0x77 w
0x78 x

Przewijanie marginesów

Następujące sekwencje umożliwiają programowi skonfigurowanie "regionu przewijania" ekranu, którego dotyczy operacja przewijania. Jest to podzbiór wierszy, które są dostosowywane, gdy ekran w przeciwnym razie przewija się, na przykład na\n" lub wystąpień zarezerwowanych. Te marginesy wpływają również na wiersze zmodyfikowane przez wstaw wiersz (IL) i usuń linię (DL), przewiń w górę (SU) i przewiń w dół (SD).

Marginesy przewijania mogą być szczególnie przydatne w przypadku części ekranu, która nie przewija się po wypełnieniu reszty ekranu, na przykład paska tytułu u góry lub paska stanu w dolnej części aplikacji.

W przypadku DECSTBM istnieją dwa parametry opcjonalne, <t> i <b>, które są używane do określania wierszy reprezentujących górne i dolne linie regionu przewijania, włącznie. Jeśli parametry zostaną pominięte, <wartość t> jest domyślnie ustawiona na 1 i <b> na bieżącą wysokość widoku.

Marginesy przewijania są buforem, więc co ważne, bufor alternatywny i bufor główny zachowują oddzielne ustawienia marginesów przewijania (więc aplikacja pełnoekranowa w buforze alternatywnym nie zatruwa marginesów buforu głównego).

Kolejność Code Opis Zachowanie
ESC [ <t> ; <b> r DECSTBM Ustaw region przewijania Ustawia marginesy przewijania maszyny wirtualnej w okienku widoku.

Tytuł okna

Następujące polecenia umożliwiają aplikacji ustawienie tytułu okna konsoli na podany <parametr ciągu> . Ciąg musi być akceptowany mniej niż 255 znaków. Jest to odpowiednik wywołania metody SetConsoleTitle z danym ciągiem.

Należy pamiętać, że te sekwencje to sekwencje OSC "Polecenie systemu operacyjnego", a nie CSI, takie jak wiele innych wymienionych sekwencji, a w związku z tym rozpoczyna się od "\x1b]", a nie "\x1b[". Jako sekwencje OSC są one zakończone terminatorem ciągu reprezentowanym jako <ST> i przesyłane za ESC \ pomocą (0x1B 0x5C). BEL (0x7) może być używany zamiast tego jako terminator, ale preferowana jest dłuższa forma.

Kolejność Opis Zachowanie
ESC ] 0 ; <struna><ST> Ustaw tytuł okna Ustawia tytuł okna konsoli na <ciąg>.
ESC ] 2 ; <struna><ST> Ustaw tytuł okna Ustawia tytuł okna konsoli na <ciąg>.

Znak zakończenia w tym miejscu to znak "Bell", "\x07"

Alternatywny bufor ekranu

*Aplikacje w stylu Nix często korzystają z alternatywnego buforu ekranu, dzięki czemu mogą modyfikować całą zawartość buforu bez wpływu na aplikację, która je uruchomiła. Alternatywny bufor jest dokładnie wymiarami okna bez żadnego regionu przewijania.

Na przykład tego zachowania rozważ uruchomienie programu vim z powłoki bash. Program Vim używa całego ekranu do edycji pliku, a następnie powrotu do powłoki bash pozostawia oryginalny bufor bez zmian.

Kolejność Opis Zachowanie
ESC [ ? 1 0 4 9 h Korzystanie z alternatywnego buforu ekranu Przełącza się do nowego alternatywnego buforu ekranu.
ESC [ ? 1 0 4 9 l Korzystanie z buforu głównego ekranu Przełącza się do głównego buforu.

Szerokość okna

Poniższe sekwencje mogą służyć do kontrolowania szerokości okna konsoli. Są one w przybliżeniu równoważne wywołaniu interfejsu API konsoli SetConsoleScreenBufferInfoEx w celu ustawienia szerokości okna.

Kolejność Code Opis Zachowanie
ESC [ ? 3 godz. DECCOLM Ustaw liczbę kolumn na 132 Ustawia szerokość konsoli na 132 kolumny szerokości.
ESC [ ? 3 l DECCOLM Ustaw liczbę kolumn na 80 Ustawia szerokość konsoli na 80 kolumn szerokości.

Resetowanie nietrwałe

Poniższa sekwencja może służyć do resetowania niektórych właściwości do ich wartości domyślnych. Następujące właściwości są resetowane do następujących wartości domyślnych (wymienione są również sekwencje kontrolujące te właściwości):

  • Widoczność kursora: widoczne (DECTEM)
  • Klawiatura liczbowa: tryb liczbowy (DECNKM)
  • Tryb kursora: tryb normalny (DECCKM)
  • Marginesy górne i dolne: Top=1, Bottom=Console height (DECSTBM)
  • Zestaw znaków: US ASCII
  • Odwzorowanie grafiki: domyślne/wyłączone (SGR)
  • Zapisz stan kursora: pozycja strony głównej (0,0) (DECSC)
Kolejność Code Opis Zachowanie
ESC [ ! p DECSTR Resetowanie nietrwałe Zresetuj niektóre ustawienia terminalu do ustawień domyślnych.

Sekwencje wejściowe

Następujące sekwencje terminalu są emitowane przez hosta konsoli w strumieniu wejściowym, jeśli flaga ENABLE_VIRTUAL_TERMINAL_INPUT jest ustawiona na dojściu buforu wejściowego przy użyciu flagi SetConsoleMode.

Istnieją dwa tryby wewnętrzne kontrolujące, które sekwencje są emitowane dla podanych kluczy wejściowych, tryb kursora i tryb klawiatury. Są one opisane w sekcji Mode Changes (Zmiany trybu).

kursora

Klawisz Tryb normalny Tryb aplikacji
Strzałka w górę ESC [ A ESC O A
Strzałka w dół ESC [ B ESC O B
Strzałka w prawo ESC [ C ESC O C
Strzałka w lewo ESC [ D ESC O D
Narzędzia główne ESC [ H ESC O H
Koniec ESC [ F ESC O F

Ponadto w przypadku naciśnięcia Ctrl przy użyciu dowolnego z tych następujące sekwencje są emitowane zamiast tego niezależnie od trybu kursora:

Klawisz Dowolny tryb
Ctrl + Strzałka w górę ESC [ 1 ; 5 A
Ctrl + strzałka w dół ESC [ 1 ; 5 B
Ctrl + strzałka w prawo ESC [ 1 ; 5 C
Ctrl + strzałka w lewo ESC [ 1 ; 5 D

Numpad i funkcji

Klawisz Kolejność
Klawisz Backspace 0x7f (DEL)
Wstrzymanie 0x1a (SUB)
Ucieczka 0x1b (ESC)
Wstawiać ESC [ 2 ~
Usuń ESC [ 3 ~
Strona w górę ESC [ 5 ~
Strona w dół 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 ~

Modyfikatorów

Alt jest traktowany przez prefiks sekwencji z ucieczką: ESC <c gdzie <c>> jest znakiem przekazywanym przez system operacyjny. Alt+Ctrl są obsługiwane w taki sam sposób, z tą różnicą, że system operacyjny będzie wstępnie przesunięty <c> do odpowiedniego znaku sterującego, który zostanie przekazany do aplikacji.

Naciśnięcie Ctrl jest zwykle przekazywane dokładnie tak, jak odebrano z systemu. Zazwyczaj jest to pojedynczy znak przesunięty w dół do zarezerwowanego miejsca znaku sterującego (0x0-0x1f). Na przykład ctrl+@ (0x40) staje się NUL (0x00), Ctrl+[ (0x5b) staje się ESC (0x1b), itp. Kilka kombinacji Ctrl jest traktowanych specjalnie zgodnie z poniższą tabelą:

Klawisz Kolejność
Ctrl + spacja 0x00 (NUL)
Ctrl + Strzałka w górę ESC [ 1 ; 5 A
Ctrl + strzałka w dół ESC [ 1 ; 5 B
Ctrl + strzałka w prawo ESC [ 1 ; 5 C
Ctrl + strzałka w lewo ESC [ 1 ; 5 D

Uwaga / Notatka

Lewy ctrl + Alt w prawo jest traktowany jako AltGr. Gdy oba te elementy będą widoczne razem, zostaną one usunięte, a wartość Unicode znaku przedstawionego przez system zostanie przekazana do obiektu docelowego. System będzie wstępnie tłumaczyć wartości AltGr zgodnie z bieżącymi ustawieniami danych wejściowych systemu.

Próbki

Przykład sekwencji terminali SGR

Poniższy kod zawiera kilka przykładów formatowania tekstu.

#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;
}

Uwaga / Notatka

W poprzednim przykładzie ciąg "\x1b[31m" jest implementacją ESC [ <n> m z <n> to 31.

Poniższa ilustracja przedstawia dane wyjściowe poprzedniego przykładu kodu.

dane wyjściowe konsoli przy użyciu polecenia sgr

Przykład włączania wirtualnego przetwarzania terminalu

Poniższy kod zawiera przykład zalecany sposób włączania przetwarzania terminali wirtualnych dla aplikacji. Celem przykładu jest pokazanie:

  1. Istniejący tryb powinien być zawsze pobierany za pośrednictwem funkcji GetConsoleMode i analizowany przed ustawieniem polecenia SetConsoleMode.

  2. Sprawdzanie, czy funkcja SetConsoleMode zwraca 0 polecenie GetLastError, a funkcja GetLastError zwraca ERROR_INVALID_PARAMETER jest bieżącym mechanizmem do określenia podczas uruchamiania w systemie na poziomie podrzędnym. Aplikacja odbierana ERROR_INVALID_PARAMETER z jedną z nowszych flag trybu konsoli w polu bitowym powinna bezpiecznie obniżyć zachowanie i spróbować ponownie.

#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;
}

Przykład wybierania funkcji aktualizacji rocznicowej

Poniższy przykład ma być bardziej niezawodnym przykładem kodu używającego różnych sekwencji ucieczki do manipulowania buforem, z naciskiem na funkcje dodane w rocznicowej aktualizacji systemu Windows 10.

W tym przykładzie użyto alternatywnego buforu ekranu, manipulowania zatrzymaniem tabulatorów, ustawianiem marginesów przewijania i zmienianiem zestawu znaków.

// 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");

}