Sequências de terminais virtuais do console
As sequências de terminais virtuais são sequências de caracteres de controle que podem controlar o movimento do cursor, a cor do console e outras operações quando gravadas no fluxo de saída. As sequências também poderão ser recebidas no fluxo de entrada em resposta a uma sequência de informações de consulta do fluxo de saída ou como uma codificação de entrada do usuário quando o modo apropriado for definido.
Você pode usar as funções GetConsoleMode e SetConsoleMode para configurar esse comportamento. Um exemplo da maneira sugerida de habilitar comportamentos de terminal virtual está incluído no final deste documento.
O comportamento das sequências a seguir baseia-se nas tecnologias de emulador de terminal VT100 e derivadas, mais especificamente no emulador de terminal xterm. Mais informações sobre as sequências de terminais podem ser encontradas em http://vt100.net e em http://invisible-island.net/xterm/ctlseqs/ctlseqs.html.
Sequências de saída
As sequências de terminal a seguir serão interceptadas pelo host do console quando gravadas no fluxo de saída, se o sinalizador ENABLE_VIRTUAL_TERMINAL_PROCESSING estiver definido no identificador de buffer de tela usando a função SetConsoleMode. Observe que o sinalizador DISABLE_NEWLINE_AUTO_RETURN também pode ser útil para emular o posicionamento do cursor e o comportamento de rolagem de outros emuladores de terminal em relação aos caracteres escritos na coluna final em qualquer linha.
Posicionamento simples do cursor
Em todas as descrições a seguir, ESC sempre é o valor hexadecimal 0x1B. Não há espaços a serem incluídos nas sequências de terminais. Sequências de terminal individuais podem ser divididas, em qualquer posição de caractere ou byte, em várias chamadas sequenciais para WriteFile ou WriteConsole, mas é recomendada a inclusão de toda a sequência em uma chamada. Para obter um exemplo de como essas sequências são usadas na prática, confira o exemplo no final deste tópico.
A tabela a seguir descreve as sequências de escape simples com um só comando de ação diretamente após o caractere ESC. Essas sequências não têm parâmetros e entram em vigor imediatamente.
Todos os comandos nessa tabela geralmente são equivalentes a chamar a API de console SetConsoleCursorPosition para posicionar o cursor.
O movimento do cursor será limitado pelo visor atual no buffer. A rolagem (se disponível) não ocorrerá.
Sequência | Abreviação | Comportamental |
---|---|---|
ESC M | RI | Índice reverso – Executa a operação reversa de \n, move o cursor uma linha para cima, mantém a posição horizontal e rola o buffer, se necessário* |
ESC 7 | DECSC | Salva a posição do cursor na memória** |
ESC 8 | DECSR | Restaura a posição do cursor da memória** |
Observação
* Se houver margens de rolagem definidas, o RI dentro das margens rolará apenas o conteúdo delas e deixará o visor inalterado. (Confira Margens de rolagem)
**Não haverá nenhum valor salvo na memória até o primeiro uso do comando save. A única maneira de acessar o valor salvo é com o comando restore.
Posicionamento do cursor
As tabelas a seguir abrangem sequências do tipo CSI (Introdutor de Sequência de Controle). Todas as sequências do CSI começam com ESC (0x1B), são seguidas por [ (colchete esquerdo, 0x5B) e podem conter parâmetros de comprimento variável para especificar mais informações para cada operação. Isso será representado pela abreviação <n>. Cada tabela abaixo é agrupada por funcionalidade com observações abaixo de cada tabela explicando como o grupo funciona.
As seguintes regras se aplicam a todos os parâmetros, a menos que indicado de outra forma:
- <n> representa a distância a ser movida e é um parâmetro opcional
- Se <n> for omitido ou for igual a 0, ele será tratado como 1
- <n> não pode ser maior que 32.767 (valor curto máximo)
- <n> não pode ser negativo
Todos os comandos nessa seção geralmente são equivalentes a chamar a API de console SetConsoleCursorPosition.
O movimento do cursor será limitado pelo visor atual no buffer. A rolagem (se disponível) não ocorrerá.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ <n> A | CUU | O cursor sobe | O cursor sobe <n> linhas |
ESC [ <n> B | CUD | O cursor desce | O cursor desce <n> linhas |
ESC [ <n> C | CUF | O cursor avança | O cursor avança (direita) <n> colunas |
ESC [ <n> D | CUB | O cursor volta | O cursor volta (esquerda) <n> colunas |
ESC [ <n> E | CNL | Cursor para a próxima linha | O cursor desce <n> linhas da posição atual |
ESC [ <n> F | CPL | Cursor para a linha anterior | Cursor sobe <n> linhas da posição atual |
ESC [ <n> G | CHA | Cursor horizontal absoluto | O cursor move-se para a <n>ª posição horizontalmente na linha atual |
ESC [ <n> d | VPA | Posição de linha vertical absoluta | O cursor move-se para a <n>ª posição verticalmente na coluna atual |
ESC [ <y> ; <x> H | CUP | Posição do cursor | *O cursor move-se para a coordenada <x>; <y> dentro do visor, em que <x> é a coluna da linha <y> |
ESC [ <y> ; <x> f | HVP | Posição vertical horizontal | *O cursor move-se para a coordenada <x>; <y> dentro do visor, em que <x> é a coluna da linha <y> |
ESC [ s | ANSISYSSC | Salvar o cursor – Emulação de Ansi.sys | **Sem parâmetros, execute uma operação para salvar o cursor, como DECSC |
ESC [ u | ANSISYSRC | Restaurar o cursor – Emulação de Ansi.sys | **Sem parâmetros, execute uma operação para restaurar o cursor, como DECRC |
Observação
Os parâmetros <x> e <y> têm as mesmas limitações que o <n> acima. Se <x> e <y> forem omitidos, eles serão definidos como 1;1.
**A documentação histórica do ANSI.sys pode ser encontrada em https://msdn.microsoft.com/library/cc722862.aspx e é implementada para fins de conveniência/compatibilidade.
Visibilidade do cursor
Os comandos a seguir controlam a visibilidade do cursor e o estado de intermitência. As sequências de DECTCEM geralmente são equivalentes a chamar a API de console SetConsoleCursorInfo para alternar a visibilidade do cursor.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ ? 12 h | ATT160 | Habilitar intermitência do cursor de texto | Iniciar a intermitência do cursor |
ESC [ ? 12 l | ATT160 | Desabilitar intermitência do cursor de texto | Parar a intermitência do cursor |
ESC [ ? 25 h | DECTCEM | Habilitar o modo de exibição do cursor de texto | Exibir o cursor |
ESC [ ? 25 l | DECTCEM | Habilitar o modo oculto do cursor de texto | Ocultar o cursor |
Dica
As sequências de habilitação terminam com um caractere H minúsculo (h
) e as sequências de desabilitação terminam com um caractere L minúsculo (l
).
Forma do cursor
Os comandos a seguir controlam e permitem a personalização da forma do cursor.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ 0 SP q | DECSCUSR | Forma do usuário | Forma de cursor padrão configurada pelo usuário |
ESC [ 1 SP q | DECSCUSR | Bloco intermitente | Forma de cursor do bloco intermitente |
ESC [ 2 SP q | DECSCUSR | Bloco constante | Forma de cursor do bloco constante |
ESC [ 3 SP q | DECSCUSR | Sublinhado intermitente | Forma de cursor do sublinhado intermitente |
ESC [ 4 SP q | DECSCUSR | Sublinhado constante | Forma de cursor do sublinhado constante |
ESC [ 5 SP q | DECSCUSR | Barra piscando | Forma de cursor da barra intermitente |
ESC [ 6 SP q | DECSCUSR | Barra constante | Forma de cursor da barra constante |
Observação
SP
é um caractere espacial literal (0x20) na posição intermediária e é seguido por q
(0x71) na posição final.
Posicionamento do visor
Todos os comandos nesta seção geralmente são equivalentes a chamar a API de console ScrollConsoleScreenBuffer para mover o conteúdo do buffer do console.
Cuidado Os nomes de comando são enganosos. Rolar refere-se a qual direção o texto move durante a operação e não a qual maneira o visor parece se mover.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ <n> S | SU | Rolar para cima | Rolar o texto para cima por <n>. Também conhecido como panorâmica para baixo, novas linhas são preenchidas na parte inferior da tela |
ESC [ <n> T | SD | Rolar para baixo | Role para baixo por <n>. Também conhecido como panorâmica para cima, novas linhas são preenchidas na parte superior da tela |
O texto é movido começando com a linha em que o cursor está. Se o cursor estiver na linha intermediária do visor, a rolagem para cima moverá a metade inferior do visor e inserirá as linhas em branco na parte inferior. A rolagem para baixo moveria a metade superior das linhas do visor e inseriria novas linhas na parte superior.
Também é importante observar que a rolagem para cima e para baixo também são afetadas pelas margens de rolagem. Rolar para cima e para baixo não afetará nenhuma linha fora das margens de rolagem.
O valor padrão para <n> é 1. e o valor pode ser opcionalmente omitido.
Modificação de dados
Todos os comandos nesta seção geralmente são equivalentes a chamar as APIs de console FillConsoleOutputCharacter, FillConsoleOutputAttribute e ScrollConsoleScreenBuffer para modificar o conteúdo do buffer de texto.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ <n> @ | ICH | Inserir caractere | Insira <n> espaços na posição atual do cursor, deslocando todo o texto existente para a direita. O texto que sai da tela à direita é removido. |
ESC [ <n> P | DCH | Excluir caractere | Exclua <n> caracteres na posição atual do cursor, alternando em caracteres de espaço da borda direita da tela. |
ESC [ <n> X | ECH | Apagar caractere | Apague <n> caracteres da posição atual do cursor, substituindo-os por um caractere de espaço. |
ESC [ <n> L | IL | Inserir linha | Insere <n> linhas no buffer na posição do cursor. A linha em que o cursor está e as linhas abaixo dele serão deslocadas para baixo. |
ESC [ <n> M | DL | Excluir linha | Exclui <n> linhas do buffer, começando com a linha em que o cursor está. |
Observação
Para IL e DL, somente as linhas nas margens de rolagem (confira Margens de rolagem) são afetadas. Se nenhuma margem for definida, as bordas de margem padrão serão o visor atual. Se as linhas forem deslocadas para baixo das margens, elas serão descartadas. Quando as linhas são excluídas, as linhas em branco são inseridas na parte inferior das margens e as linhas fora do visor nunca são afetadas.
Para cada uma das sequências, o valor padrão de <n> se ele for omitido será 0.
Para os seguintes comandos, o parâmetro <n> tem três valores válidos:
- 0 apaga da posição atual do cursor (inclusive) até o fim da linha/tela
- 1 apaga do início da linha/tela até e inclusive a posição atual do cursor
- 2 apaga toda a linha/tela
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ <n> J | ED | Apagar na tela | Substitua todo o texto no visor/tela atual especificado em <n> por caracteres de espaço |
ESC [ <n> K | EL | Apagar na linha | Substitua todo o texto na linha com o cursor especificado em <n> por caracteres de espaço |
Formatação de texto
Todos os comandos nesta seção geralmente são equivalentes a chamar as APIs de console SetConsoleTextAttribute para ajustar a formatação de todas as gravações futuras para o buffer de texto de saída do console.
Esse comando é especial, pois a posição <n> abaixo pode aceitar entre 0 e 16 parâmetros separados por ponto e vírgula.
Quando nenhum parâmetro for especificado, ele será tratado como um parâmetro 0.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ <n> m | SGR | Definir a representação de gráficos | Definir o formato da tela e do texto conforme especificado por <n> |
A tabela de valores a seguir pode ser usada em <n> para representar modos de formatação diferentes.
Os modos de formatação são aplicados da esquerda para a direita. A aplicação das opções de formatação concorrentes fará com que a opção mais à direita tenha precedência.
Para opções que especificam cores, as cores serão usadas conforme definido na tabela de cores do console que pode ser modificada usando a API SetConsoleScreenBufferInfoEx. Se a tabela for modificada para fazer com que a posição "azul" na tabela exiba um sombreamento de RGB vermelho, todas as chamadas para o Primeiro plano azul exibirão a cor vermelha até que ela seja alterada.
Valor | Descrição | Comportamento |
---|---|---|
0 | Default | Retorna todos os atributos para o estado padrão antes da modificação |
1 | Negrito/brilhante | Aplica o sinalizador de brilho/intensidade à cor de primeiro plano |
22 | Sem negrito/brilhante | Remove o sinalizador de brilho/intensidade da cor de primeiro plano |
4 | Sublinhado | Adiciona o sublinhado |
24 | Sem sublinhado | Remove o sublinhado |
7 | Negativo | Altera as cores do primeiro plano e da tela de fundo |
27 | Positivo (sem negativo) | Retorna o primeiro plano/tela de fundo para normal |
30 | Primeiro plano preto | Aplica o preto sem negrito/brilhante no primeiro plano |
31 | Primeiro plano vermelho | Aplica o vermelho sem negrito/brilhante no primeiro plano |
32 | Primeiro plano verde | Aplica o verde sem negrito/brilhante no primeiro plano |
33 | Primeiro plano amarelo | Aplica o amarelo sem negrito/brilhante no primeiro plano |
34 | Primeiro plano azul | Aplica o azul sem negrito/brilhante no primeiro plano |
35 | Primeiro plano magenta | Aplica o magenta sem negrito/brilhante no primeiro plano |
36 | Primeiro plano ciano | Aplica o ciano sem negrito/brilhante no primeiro plano |
37 | Primeiro plano branco | Aplica o branco sem negrito/brilhante no primeiro plano |
38 | Primeiro plano estendido | Aplica o valor de cor estendida no primeiro plano (veja os detalhes abaixo) |
39 | Padrão de primeiro plano | Aplica-se somente aos padrões do primeiro plano (veja 0) |
40 | Tela de fundo preta | Aplica o preto sem negrito/brilhante na tela de fundo |
41 | Tela de fundo vermelha | Aplica o vermelho sem negrito/brilhante na tela de fundo |
42 | Tela de fundo verde | Aplica o verde sem negrito/brilhante na tela de fundo |
43 | Tela de fundo amarela | Aplica o amarelo sem negrito/brilhante na tela de fundo |
44 | Tela de fundo azul | Aplica o azul sem negrito/brilhante na tela de fundo |
45 | Tela de fundo magenta | Aplica o magenta sem negrito/brilhante na tela de fundo |
46 | Tela de fundo ciano | Aplica o ciano sem negrito/brilhante na tela de fundo |
47 | Tela de fundo branca | Aplica o branco sem negrito/brilhante na tela de fundo |
48 | Tela de fundo estendida | Aplica o valor de cor estendida na tela de fundo (veja os detalhes abaixo) |
49 | Padrão da tela de fundo | Aplica-se somente aos padrões da tela de fundo (veja 0) |
90 | Primeiro plano preto brilhante | Aplica o preto em negrito/brilhante no primeiro plano |
91 | Primeiro plano vermelho brilhante | Aplica o vermelho em negrito/brilhante no primeiro plano |
92 | Primeiro plano em verde brilhante | Aplica o verde em negrito/brilhante no primeiro plano |
93 | Primeiro plano amarelo brilhante | Aplica o amarelo em negrito/brilhante no primeiro plano |
94 | Primeiro plano azul brilhante | Aplica o azul em negrito/brilhante no primeiro plano |
95 | Primeiro plano magenta brilhante | Aplica o magenta em negrito/brilhante no primeiro plano |
96 | Primeiro plano ciano brilhante | Aplica o ciano em negrito/brilhante no primeiro plano |
97 | Primeiro plano branco brilhante | Aplica o branco em negrito/brilhante no primeiro plano |
100 | Tela de fundo preta brilhante | Aplica o preto em negrito/brilhante na tela de fundo |
101 | Tela de fundo vermelha brilhante | Aplica o vermelho em negrito/brilhante na tela de fundo |
102 | Tela de fundo verde brilhante | Aplica o verde em negrito/brilhante na tela de fundo |
103 | Tela de fundo amarela brilhante | Aplica o amarelo em negrito/brilhante na tela de fundo |
104 | Tela de fundo azul brilhante | Aplica o azul em negrito/brilhante na tela de fundo |
105 | Tela de fundo magenta brilhante | Aplica o magenta em negrito/brilhante na tela de fundo |
106 | Tela de fundo ciano brilhante | Aplica o ciano em negrito/brilhante na tela de fundo |
107 | Tela de fundo branca brilhante | Aplica o branco em negrito/brilhante na tela de fundo |
Cores estendidas
Alguns emuladores de terminal virtual dão suporte a uma paleta de cores maior do que as 16 cores fornecidas pelo Console do Windows. Para essas cores estendidas, o Console do Windows escolherá a cor apropriada mais próxima da tabela de 16 cores existente para a tela. Diferentemente dos valores de SGR típicos acima, os valores estendidos consumirão parâmetros adicionais após o indicador inicial de acordo com a tabela a seguir.
Subsequência de SGR | Descrição |
---|---|
38 ; 2 ; <r> ; <g> ; <b> | Define a cor de primeiro plano como o valor de RGB especificado nos parâmetros <r>, <g>, <b>* |
48 ; 2 ; <r> ; <g> ; <b> | Define a cor da tela de fundo como o valor de RGB especificado nos parâmetros <r>, <g>, <b>* |
38 ; 5 ; <s> | Define a cor de primeiro plano como o índice <s> na tabela de cores 88 ou 256* |
48 ; 5 ; <s> | Define a cor da tela de fundo como o índice <s> na tabela de cores 88 ou 256 |
*As paletas de cores 88 e 256 mantidas internamente para comparação são baseadas no emulador de terminal xterm. As tabelas de comparação/arredondamento não podem ser modificadas neste momento.
Cores da tela
O comando a seguir permite que o aplicativo defina os valores da paleta cores da tela para qualquer valor de RGB.
Os valores de RGB devem ser valores hexadecimais entre 0
e ff
, separados pelo caractere de barra invertida (por exemplo, rgb:1/24/86
).
Observe que essa sequência é uma sequência do OSC ("Comando do sistema operacional"), e não de um CSI como muitas das outras sequências listadas e, como tal, ela começa com “\x1b]”, não “\x1b[”. Como sequências de OSC, elas são encerradas com um terminador de cadeia de caracteres representado como <ST>
e transmitido com ESC \
(0x1B 0x5C
). Em vez disso, BEL
(0x7
) pode ser usado como o terminador, mas a forma mais longa é preferencial.
Sequência | Descrição | Comportamento |
---|---|---|
ESC ] 4 ; <i> ; rgb : <r> / <g> / <b><ST> | Modificar cores da tela | Define o índice da paleta de cores da tela <i> para os valores de RGB especificados em <r>, <g>, <b> |
Alterações no modo
Essas são as sequências que controlam os modos de entrada. Há dois conjuntos diferentes de modos de entrada, o Modo de Teclas do Cursor e o Modo de Teclas do Teclado. O Modo de Teclas do Cursor controla as sequências emitidas pelas teclas de direção, bem como as teclas Home e End, enquanto o Modo de Teclas do Teclado controla as sequências emitidas principalmente pelas teclas no teclado numérico, bem como as teclas de função.
Cada um desses modos são configurações boolianas simples – o Modo de Teclas do Cursor é Normal (padrão) ou Aplicativo e o Modo de Teclas do Teclado é Numérico (padrão) ou Aplicativo.
Confira as seções Teclas do cursor e Chaves de função e do teclado numérico para obter as sequências emitidas nesses modos.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC = | DECKPAM | Habilitar o modo de aplicativo do teclado | As teclas do teclado emitirão as sequências do Modo de Aplicativo. |
ESC > | DECKPNM | Habilitar o modo numérico do teclado | As teclas do teclado emitirão as sequências do Modo Numérico. |
ESC [ ? 1 h | DECCKM | Habilitar o modo de aplicativo das teclas de cursor | As teclas do teclado emitirão as sequências do Modo de Aplicativo. |
ESC [ ? 1 l | DECCKM | Desabilitar o modo de aplicativo das teclas de cursor (usar o modo normal) | As teclas do teclado emitirão as sequências do Modo Numérico. |
Estado de consulta
Todos os comandos nesta seção geralmente são equivalentes a chamar as APIs de console Get* para recuperar informações de status sobre o estado atual do buffer do console.
Observação
Essas consultas emitirão as respostas para o fluxo de entrada do console imediatamente depois de serem reconhecidas no fluxo de saída, enquanto ENABLE_VIRTUAL_TERMINAL_PROCESSING é definido. O sinalizador ENABLE_VIRTUAL_TERMINAL_INPUT não se aplica a comandos de consulta, pois supõe-se que um aplicativo que faz a consulta sempre desejará receber a resposta.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ 6 n | DECXCPR | Relatar a posição do cursor | ESC ESC [ <r> ; <c>, em que <r> é a linha do cursor e <c> é a coluna do cursor |
ESC [ 0 c | DA | Atributos do dispositivo | Relatar a identidade do terminal. Emitirá “\x1b[?1;0c”, indicando "VT101 sem opções". |
Tabulações
Embora o console do Windows tradicionalmente espere que as tabulações tenham apenas oito caracteres de largura, os aplicativos nix* que usam determinadas sequências podem manipular onde as paradas de tabulação estão dentro das janelas do console para otimizar o movimento do cursor pelo aplicativo.
As sequências a seguir permitem que um aplicativo defina os locais de parada de tabulação na janela do console, remova-os e navegue entre eles.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC H | HTS | Definir a tabulação horizontal | Define uma parada de tabulação na coluna atual em que o cursor está. |
ESC [ <n> I | CHT | Tabulação horizontal do cursor (para frente) | Avance o cursor para a próxima coluna (na mesma linha) com uma parada de tabulação. Se não houver mais paradas de tabulação, ele será movido para a última coluna da linha. Se o cursor estiver na última coluna, ele será movido para a primeira coluna da próxima linha. |
ESC [ <n> Z | CBT | Tabulação de regressão do cursor | Mova o cursor para a coluna anterior (na mesma linha) com uma parada de tabulação. Se não houver mais paradas de tabulação, o cursor será movido para a primeira coluna. Se o cursor estiver na primeira coluna, não mova o cursor. |
ESC [ 0 g | TBC | Limpar tabulação (coluna atual) | Limpa a parada de tabulação na coluna atual, se houver uma. Caso contrário, não faz nada. |
ESC [ 3 g | TBC | Limpar tabulação (todas as colunas) | Limpa todas as paradas de tabulação definidas no momento. |
- Para o CHT e o CBT, <n> é um parâmetro opcional que (padrão = 1) indica quantas vezes o cursor deve avançar na direção especificada.
- Se não houver nenhuma parada de tabulação definida por meio de HTS, o CHT e o CBT tratarão a primeira e a última coluna da janela como as duas únicas paradas de tabulação.
- Usar o HTS para definir uma parada de tabulação também fará com que o console navegue até a próxima parada de tabulação na saída de um caractere de TAB (0x09, ‘\t’), da mesma maneira que o CHT.
Designar o conjunto de caracteres
As sequências a seguir permitem que um programa altere o mapeamento de um conjunto de caracteres ativo. Isso permite que um programa emita caracteres ASCII de 7 bits, mas que eles sejam exibidos como outros glifos na própria tela do terminal. Atualmente, os dois conjuntos de caracteres com suporte são ASCII (padrão) e o DEC Special Graphics Character Set. Confira http://vt100.net/docs/vt220-rm/table2-4.html para obter uma lista de todos os caracteres representados pelo DEC Special Graphics Character Set.
Sequência | Descrição | Comportamento |
---|---|---|
ESC ( 0 | Designar o conjunto de caracteres – Desenho de linha do DEC | Habilita o modo de desenho de linha do DEC |
ESC ( B | Designar o conjunto de caracteres – US ASCII | Habilita o modo ASCII (padrão) |
Notavelmente, o modo de Desenho de Linha do DEC é usado para desenhar bordas em aplicativos de console. A tabela a seguir mostra qual caractere ASCII é mapeado para qual caractere de desenho de linha.
Hex | ASCII | Desenho de linha do DEC |
---|---|---|
0x6a | j | ┘ |
0x6b | k | ┐ |
0x6c | l | ┌ |
0x6d | m | └ |
0x6e | n | ┼ |
0x71 | q | ─ |
0x74 | t | ├ |
0x75 | u | ┤ |
0x76 | v | ┴ |
0x77 | w | ┬ |
0x78 | x | │ |
Margens de rolagem
As sequências a seguir permitem que um programa configure a "região de rolagem" da tela que é afetada pelas operações de rolagem. Esse é um subconjunto das linhas que são ajustadas quando a tela rolar, por exemplo, em um ‘\n’ ou RI. Essas margens também afetam as linhas modificadas por Inserir Linha (IL) e Excluir Linha (DL), Rolar para Cima (SU) e Rolar para Baixo (SD).
As margens de rolagem podem ser especialmente úteis para ter uma parte da tela que não rola quando o restante da tela é preenchido, como ter uma barra de título na parte superior ou uma barra de status na parte inferior do seu aplicativo.
Para DECSTBM, há dois parâmetros opcionais, <t> e <b>, que são usados para especificar as linhas que representam as linhas superior e inferior da região de rolagem, inclusive. Se os parâmetros forem omitidos, o padrão de <t> será 1 e o padrão de <b> será a altura atual do visor.
As margens de rolagem são por buffer, portanto, é importante que o Buffer Alternado e o Buffer Principal mantenham configurações de margens de rolagem separadas (de modo que um aplicativo de tela inteira no buffer alternado não contaminará as margens do buffer principal).
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ <t> ; <b> r | DECSTBM | Definir a região de rolagem | Define as margens de rolagem de VT do visor. |
Título da janela
Os comandos a seguir permitem que o aplicativo defina o título da janela do console para determinado parâmetro <string>. A cadeia de caracteres precisa ter menos de 255 caracteres para ser aceita. Isso é equivalente a chamar o SetConsoleTitle com a cadeia de caracteres fornecida.
Observe que essas sequências são sequências do OSC ("Comando do sistema operacional"), e não de um CSI como muitas das outras sequências listadas e, como tal, elas começam com “\x1b]”, não “\x1b[”. Como sequências de OSC, elas são encerradas com um terminador de cadeia de caracteres representado como <ST>
e transmitido com ESC \
(0x1B 0x5C
). Em vez disso, BEL
(0x7
) pode ser usado como o terminador, mas a forma mais longa é preferencial.
Sequência | Descrição | Comportamento |
---|---|---|
ESC ] 0 ; <cadeia de caracteres><ST> | Window_Title | Define o título da janela do console como <string>. |
ESC ] 2 ; <cadeia de caracteres><ST> | Window_Title | Define o título da janela do console como <string>. |
O caractere de encerramento aqui é o caractere “Sino”, ‘\x07’
Buffer de tela alternativo
*Os aplicativos de estilo Nix geralmente utilizam um buffer de tela alternativo, para que eles possam modificar todo o conteúdo do buffer, sem afetar o aplicativo que os iniciou. O buffer alternativo tem exatamente as mesmas dimensões da janela, sem nenhuma região retorno de rolagem.
Para obter um exemplo desse comportamento, considere quando o VIM é iniciado no Bash. O VIM usa toda a tela para editar o arquivo, e retornar ao Bash deixa o buffer original inalterado.
Sequência | Descrição | Comportamento |
---|---|---|
ESC [ ? 1 0 4 9 h | Usar o buffer de tela alternativo | Alterna para um novo buffer de tela alternativo. |
ESC [ ? 1 0 4 9 l | Usar o buffer de tela principal | Alterna para o buffer principal. |
Largura da janela
As sequências a seguir podem ser usadas para controlar a largura da janela do console. Elas são aproximadamente equivalentes à chamada da API de console SetConsoleScreenBufferInfoEx para definir a largura da janela.
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ ? 3 h | DECCOLM | Definir número de colunas como 132 | Define a largura do console como 132 colunas de largura. |
ESC [ ? 3 l | DECCOLM | Definir número de colunas como 80 | Define a largura do console como 80 colunas de largura. |
Redefinição reversível
A sequência a seguir pode ser usada para redefinir determinadas propriedades para os valores padrão. As seguintes propriedades são redefinidas para os seguintes valores padrão (as sequências que controlam essas propriedades também são listadas):
- Visibilidade do cursor: visível (DECTEM)
- Teclado numérico: Modo numérico (DECNKM)
- Modo de teclas de cursor: Modo normal (DECCKM)
- Margens superior e inferior: superior = 1, inferior = altura do console (DECSTBM)
- Conjunto de caracteres: ASCII dos EUA
- Representação gráfica: padrão/desativada (SGR)
- Salvar estado do cursor: posição inicial (0,0) (DECSC)
Sequência | Código | Descrição | Comportamento |
---|---|---|---|
ESC [ ! p | DECSTR | Redefinição reversível | Redefina determinadas configurações de terminal para os padrões. |
Sequências de entrada
As sequências de terminal a seguir serão emitidas pelo host do console no fluxo de entrada se o sinalizador ENABLE_VIRTUAL_TERMINAL_INPUT estiver definido no identificador do buffer de entrada usando o sinalizador SetConsoleMode.
Há dois modos internos que controlam quais sequências são emitidas para as chaves de entrada determinadas, o Modo de Teclas do Cursor e o Modo de Teclas do Teclado. Eles são descritos na seção Alterações do modo.
Teclas do cursor
Chave | Modo normal | Modo de aplicativo |
---|---|---|
Seta para cima | ESC [ A | ESC O A |
Seta para Baixo | ESC [ B | ESC O B |
Seta para a Direita | ESC [ C | ESC O C |
Seta para a Esquerda | ESC [ D | ESC O D |
Página Inicial | ESC [ H | ESC O H |
Fim | ESC [ F | ESC O F |
Além disso, se Ctrl for pressionado com qualquer uma dessas teclas, as seguintes sequências serão emitidas, independentemente do Modo de Teclas do Cursor:
Chave | Qualquer modo |
---|---|
Ctrl + Seta para cima | ESC [ 1 ; 5 A |
Ctrl + Seta para baixo | ESC [ 1 ; 5 B |
Ctrl + Seta para a direita | ESC [ 1 ; 5 C |
Ctrl + Seta para a esquerda | ESC [ 1 ; 5 D |
Teclas de função e teclado numérico
Chave | Sequência |
---|---|
Backspace | 0x7f (DEL) |
Pausar | 0x1a (SUB) |
Escape | 0x1b (ESC) |
Insert | ESC [ 2 ~ |
Excluir | 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 ~ |
Modificadores
Alt é tratado prefixando a sequência com um escape: ESC <c> onde <c> é o caractere passado pelo sistema operacional. Alt + Ctrl é tratado da mesma forma, exceto pelo fato que o sistema operacional terá deslocado previamente a tecla <c> para o caractere de controle apropriado que será retransmitido para o aplicativo.
O Ctrl geralmente é passado exatamente como ele é recebido do sistema. Normalmente, há um caractere deslocado para baixo no espaço reservado do caractere de controle (0x0-0x1f). Por exemplo, Ctrl+@ (0x40) torna-se NULO (0x00), Ctrl+[ (0x5b) torna-se ESC (0x1b), etc. Algumas combinações de teclas Ctrl são tratadas de modo especial de acordo com a tabela a seguir:
Chave | Sequência |
---|---|
Ctrl+Espaço | 0x00 (NUL) |
Ctrl + Seta para cima | ESC [ 1 ; 5 A |
Ctrl + Seta para baixo | ESC [ 1 ; 5 B |
Ctrl + Seta para a direita | ESC [ 1 ; 5 C |
Ctrl + Seta para a esquerda | ESC [ 1 ; 5 D |
Observação
Ctrl à esquerda + Alt à direita é tratado como AltGr. Quando ambos estiverem juntos, eles serão removidos e o valor Unicode do caractere apresentado pelo sistema será passado para o destino. O sistema converterá previamente os valores de AltGr de acordo com as configurações de entrada do sistema atual.
Exemplos
Exemplo de sequências de terminais de SGR
O código a seguir fornece vários exemplos de formatação de texto.
#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;
}
Observação
No exemplo anterior, a cadeia de caracteres '\x1b[31m
' é a implementação de ESC [ <n> m com <n> igual a 31.
O gráfico a seguir mostra a saída do exemplo de código anterior.
Exemplo de habilitação do processamento de terminal virtual
O código a seguir fornece um exemplo da maneira recomendada para habilitar o processamento de terminal virtual para um aplicativo. A intenção do exemplo é demonstrar:
O modo existente sempre deve ser recuperado por meio do GetConsoleMode e analisado antes de ser definido com SetConsoleMode.
Verificar se SetConsoleMode retornar
0
e se GetLastError retornar ERROR_INVALID_PARAMETER é o mecanismo atual para determinar quando executar um sistema de nível inferior. Um aplicativo que recebe ERROR_INVALID_PARAMETER com um dos novos sinalizadores de modo de console no campo de bits deve degradar o comportamento normalmente e tentar de novo.
#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;
}
Exemplo de recursos selecionados de atualização de aniversário
O exemplo a seguir destina-se a ser um exemplo mais robusto de código usando uma variedade de sequências de escape para manipular o buffer, com ênfase nos recursos adicionados na Atualização de Aniversário do Windows 10.
Este exemplo usa o buffer de tela alternativo, manipulando paradas de tabulação, definindo margens de rolagem e alterando o conjunto de caracteres.
// 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");
}