[How To] Just another code with examples of VT (ANSI) escape sequences

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

[How To] Just another code with examples of VT (ANSI) escape sequences

#1 Post by aGerman » 16 Jan 2022 06:52

Uncomment one of the CALL commands beginning in line 35 in order to check how the sequences of your interest behave. Scroll down to the belonging label, read the code and the comments.
NOTE: Explicitly save the code UTF-8-encoded without BOM!

Steffen

Code: Select all

:: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
:: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
:: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
:: https://espterm.github.io/docs/VT100%20escape%20codes.html

@echo off &setlocal
:: define variables for all C0 control characters you may ever need in a VT emulator + DEL (C1 control characters may not even be supported)
for /f "tokens=1-15 delims=," %%a in ('forfiles.exe /p "%__APPDIR__%." /m "cmd.exe" /c^
  "cmd.exe /q /d /c echo(ENQ=0x05,BEL=0x07,BS=0x08,HT=0x09,VT=0x0b,FF=0x0c,SO=0x0e,SI=0x0f,DC1=0x11,DC3=0x13,CAN=0x18,SUB=0x1a,ESC=0x1b,SP=0x20,DEL=0x7f"'
) do set "%%a"&set "%%b"&set "%%c"&set "%%d"&set "%%e"&set "%%f"&set "%%g"&set "%%h"&set "%%i"&set "%%j"&set "%%k"&set "%%l"&set "%%m"&set "%%n"&set "%%o"
set "CR="&for /f "skip=1" %%i in ('echo(^|replace.exe ? . /u /w') do if not defined CR (set "CR=%%i"&set LF=^
%= do not alter this =%
)

:: define convenience variables
set "IND=%ESC%D"   &REM Index
set "NEL=%ESC%E"   &REM Next Line
set "HTS=%ESC%H"   &REM Tab Set
set "RI=%ESC%M"    &REM Reverse Index
set "SS2=%ESC%N"   &REM Single Shift Select of G2 Character Set
set "SS3=%ESC%O"   &REM Single Shift Select of G3 Character Set
set "DCS=%ESC%P"   &REM Device Control String
set "SPA=%ESC%V"   &REM Start of Guarded Area
set "EPA=%ESC%W"   &REM End of Guarded Area
set "SOS=%ESC%X"   &REM Start of String
set "DECID=%ESC%Z" &REM Return Terminal ID (Obsolete form of CSI c)
set "CSI=%ESC%["   &REM Control Sequence Introducer
set "ST=%ESC%\"    &REM String Terminator
set "OSC=%ESC%]"   &REM Operating System Command
set "PM=%ESC%^^"   &REM Privacy Message
set "APC=%ESC%_"   &REM Application Program Command

set "wr=<nul set /p =" &REM write without new line
set "nil=%CSI%12t"     &REM ignored sequence which can be used to overcome the behavior of %wr% to remove leading white spaces (e.g. %wr%%nil%     foo)

::call :scroll
::call :colorsTrue
::call :colors256
::call :colors16
::call :textFormat
::call :eraseAndInsert
::call :cursorPosition
::call :cursorAppearance
::call :specialChars       &REM still buggy in Console
::call :singleByteCommands
::call :utf8               &REM still buggy in Console
::call :title
::call :link               &REM requires Terminal
::call :clipboard          &REM requires Terminal
::call :doubleHeightWidth  &REM requires Windows 11 Console, Terminal does not yet support it

exit /b

:::::::::::::::::::::::::::::::::::::::::
:scroll
cls
for /l %%i in (1 1 1000) do echo %%i
>nul timeout /t 2 /nobreak
:: scroll 10 down
%wr%%CSI%10T
>nul timeout /t 2 /nobreak
:: scroll 10 up
%wr%%CSI%10S
>nul timeout /t 2 /nobreak
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:colorsTrue
cls
:: foreground CSI 38 ; 2 ; R ; G ; B m
%wr%%CSI%38;2;255;0;0mR%CSI%38;2;0;255;0mG%CSI%38;2;0;0;255mB
echo %CSI%0m
:: background CSI 48 ; 2 ; R ; G ; B m
%wr%%CSI%48;2;255;0;0mR%CSI%48;2;0;255;0mG%CSI%48;2;0;0;255mB
echo %CSI%0m
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:colors256
cls
:: foreground CSI 38 ; 5 ; N m
for /l %%i in (0 1 255) do (%wr%%CSI%38;5;%%im %%i )
echo %CSI%0m
:: background CSI 48 ; 5 ; N m
for /l %%i in (0 1 255) do (%wr%%CSI%48;5;%%im %%i )
echo %CSI%0m
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:colors16
cls
for /l %%i in (30 1 37) do (
  for /l %%j in (40 1 47) do (%wr%%CSI%%%i;%%jm  %%i;%%j )
  echo %CSI%0m
)
for /l %%i in (90 1 97) do (
  for /l %%j in (100 1 107) do (%wr%%CSI%%%i;%%jm %%i;%%j )
  echo %CSI%0m
)
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:textFormat
cls
echo %CSI%1mbold%CSI%0m
echo %CSI%2mfaint%CSI%0m
echo %CSI%3mitalic%CSI%0m
echo %CSI%4munderlined%CSI%0m
echo %CSI%5mblinking%CSI%0m
echo %CSI%7minverse%CSI%0m
echo %CSI%8m(almost) invisible%CSI%0m
echo %CSI%9mcrossed out%CSI%0m
echo %CSI%21mdoubly underlined%CSI%0m
echo %CSI%1;3;4mbold italic underlined%CSI%0m
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:eraseAndInsert
cls
%wr%%ESC%(0
for /l %%i in (1 1 20) do echo ````````````````````````````````````````
%wr%%ESC%(B

:: cursor 10 up
%wr%%CSI%10A
>nul timeout /t 1 /nobreak
:: insert 2 lines
%wr%%CSI%2L
>nul timeout /t 1 /nobreak
:: erase below
%wr%%CSI%0J
>nul timeout /t 1 /nobreak
:: cursor 5 up
%wr%%CSI%5A
>nul timeout /t 1 /nobreak
:: erase above
%wr%%CSI%1J
>nul timeout /t 1 /nobreak
:: cursor 2 down
%wr%%CSI%2B
:: cursor 10 right
%wr%%CSI%10C
>nul timeout /t 1 /nobreak
:: insert 5 spaces
%wr%%CSI%5@
>nul timeout /t 1 /nobreak
:: erase left
%wr%%CSI%1K
>nul timeout /t 1 /nobreak
:: erase 5 rigth and move the rest of the line left
%wr%%CSI%5P
>nul timeout /t 1 /nobreak
:: erase rigth
%wr%%CSI%0K
>nul timeout /t 1 /nobreak
:: cursor 1 up
%wr%%CSI%1A
>nul timeout /t 1 /nobreak
:: erase whole line
%wr%%CSI%2K
>nul timeout /t 1 /nobreak
:: erase all
%wr%%CSI%2J
>nul timeout /t 1 /nobreak
:: cursor home
%wr%%CSI%H
>nul timeout /t 1 /nobreak

pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:cursorPosition
cls
%wr%%ESC%(0
for /l %%i in (1 1 20) do echo ````````````````````````````````````````
%wr%%ESC%(B

:: store cursor position
%wr%%ESC%7

>nul timeout /t 1 /nobreak
:: 15 up
%wr%%CSI%15A1
>nul timeout /t 1 /nobreak
:: 3 down (same column)
%wr%%CSI%3B2
>nul timeout /t 1 /nobreak
:: 20 forward
%wr%%CSI%20C3
>nul timeout /t 1 /nobreak
:: 10 backward
%wr%%CSI%10D4
>nul timeout /t 1 /nobreak
:: 3 down to beginning of line
%wr%%CSI%3E5
>nul timeout /t 1 /nobreak
::  20 forward
%wr%%CSI%20C6
>nul timeout /t 1 /nobreak
:: 3 up to beginning of line
%wr%%CSI%1F7
>nul timeout /t 1 /nobreak
:: 4th column same line
%wr%%CSI%4G8
>nul timeout /t 1 /nobreak
:: 5th column; 10th line
%wr%%CSI%5;10H9
>nul timeout /t 1 /nobreak
:: 2 tabs forward
%wr%%CSI%2I10
>nul timeout /t 1 /nobreak
:: 2 tabs backward
%wr%%CSI%2Z11
>nul timeout /t 1 /nobreak
:: home
%wr%%CSI%H12
>nul timeout /t 1 /nobreak

:: restore cursor position
%wr%%ESC%8
>nul timeout /t 1 /nobreak

pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:cursorAppearance
cls
:: stop blinking
%wr%%CSI%?12l
>nul timeout /t 3 /nobreak
:: start blinking
%wr%%CSI%?12h
>nul timeout /t 3 /nobreak

:: hide cursor
%wr%%CSI%?25l
>nul timeout /t 3 /nobreak
:: show cursor
%wr%%CSI%?25h
>nul timeout /t 3 /nobreak

:: blinking block
%wr%%CSI%1%SP%q
>nul timeout /t 3 /nobreak
:: steady block
%wr%%CSI%2%SP%q
>nul timeout /t 3 /nobreak
:: blinking underline
%wr%%CSI%3%SP%q
>nul timeout /t 3 /nobreak
:: steady underline
%wr%%CSI%4%SP%q
>nul timeout /t 3 /nobreak
:: blinking bar
%wr%%CSI%5%SP%q
>nul timeout /t 3 /nobreak
:: steady bar
%wr%%CSI%6%SP%q
>nul timeout /t 3 /nobreak
:: default
%wr%%CSI%0%SP%q
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:specialChars
cls
%wr%%ESC%(0
::   ▒ ° ± ┘ ┐ ┌ └ ┼ ⎺ ⎻ ─ ⎼ ⎽ ├ ┤ ┴ ┬ │ ≤ ≥ · ♦  ≠ π £
echo a f g j k l m n o p q r s t u v w x y z ~ ` ^| { }
%wr%%ESC%(B
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:singleByteCommands
cls
:: a beep or bell ring is played, WT also shows a bell icon in the title of the tab
echo Ring the bell%BEL%
pause
:: D is overwritten with d
echo Backspace sets the cursor one column backwarD%BS%d
pause
echo Horizontal%HT%Tab
pause
%wr%New Line using Vertical Tab%VT%
pause
%wr%New Line using Form Feed%FF%
pause
setlocal EnableDelayedExpansion
%wr%New Line using Line Feed!LF!
endlocal
pause
setlocal EnableDelayedExpansion
:: M is overwritten with C
echo Marriage Return sets the cursor to the beginning of the line!CR!C
endlocal
pause
:: %SP% is actually just a space. This variable is only defined because you'll find SP in the manpage whenever the sequence contains a space.
echo Just%SP%spaces%SP%between%SP%the%SP%words
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:title
cls
:: update the title
%wr%%OSC%2;foo%ST%
pause
:: the BEL character can be used instead of the string terminator
%wr%%OSC%2;bar%BEL%
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:utf8
:: note that the script code itself is UTF-8-encoded
cls
:: select UTF-8 character set
%wr%%ESC%%%G
echo ☺漢€Я
:: select default character set
%wr%%ESC%%%@
echo ☺漢€Я
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:link
cls
:: hyperlink
echo Page %OSC%8;;https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda%ST%"Hyperlinks in terminal emulators"%OSC%8;;%ST% describes it.
>"foobar~.txt" echo foobar
echo Open %OSC%8;;file:///%cd%\foobar~.txt%ST%foobar~.txt%OSC%8;;%ST% file.
pause
del "foobar~.txt"
exit /b

:::::::::::::::::::::::::::::::::::::::::
:clipboard
cls
:: clear clipboard
powershell.exe -nop -ep Bypass -c "Set-Clipboard -Value $null"
:: copy to clipboard: OSC 52 ; c ; <bas64-encoded text> ST
%wr%%OSC%52;c;SGVsbG8sIFdvcmxkIQ==%ST%
:: read what we just cached
powershell.exe -nop -ep Bypass -c "Get-Clipboard"
pause
exit /b

:::::::::::::::::::::::::::::::::::::::::
:doubleHeightWidth
cls
:: upper half
echo %ESC%#3Double Height (implies Double Width)
:: bottom half
echo %ESC%#4Double Height (implies Double Width)

echo %ESC%#6Double Width only
pause
exit /b
// Edit: Use path and name of the cmd to ensure values for /p and /m don't contain special characters.

jfl
Posts: 226
Joined: 26 Oct 2012 06:40
Location: Saint Hilaire du Touvet, France
Contact:

Re: [How To] Just another code with examples of VT (ANSI) escape sequences

#2 Post by jfl » 24 Jan 2022 04:56

Excellent!

I did not expect most of them to also work in the old console. What's the minimum version of Windows where all this will work?
(In Windows 11, even those flagged "still buggy in Console" do work fine there.)

Also I had never seen that method for generating the CR character.
Is this faster than the usual copy /z trick maybe?

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: [How To] Just another code with examples of VT (ANSI) escape sequences

#3 Post by aGerman » 24 Jan 2022 11:04

Hmm, I upgraded to Win11 quite a while ago. Let's see what I still recall.

A couple of single byte commands have been working all the time. Such like CR, LF, HT, BS, BEL ...
However, escape sequence came (back) with the new Win10 console. IIRC some of the sequences are at least not fully supported on Win10 though. For example ESC%G for turning the charset to UTF-8, or italic and blinking text are unsupported.
The "still buggy" is related to the Win11 console. While those ecape sequences are supported, the implementation of the conhost window restricts their effectiveness. To be more specific, some characters can't be represented, even if the font in the console is set the same as in the terminal.
consolecrap.png
consolecrap.png (2.57 KiB) Viewed 4058 times
Steffen

Post Reply