If, for convenience reasons, you don't mind using a lightweight third-party tool, here's what you get:
- vt.exe behaves almost like ECHO in terms of processing the string passed. That is, it is not required to enclose strings that contain spaces in quotation marks. Quotation marks are used as literal characters.
- Only the separating whitespace towards the passed string is removed. However, subsequent leading whitespaces in the string are preserved.
- By default, vt.exe doesn't append a new line. This is particularly useful if only an escape sequence is to be printed. However, "\n" (not case-sensitive) can be used to print a new line, and it can occur at any position in the string, even multiple times.
- It isn't necessary to use an ESC character for escape sequences. It's also possible to use "\e" (not case-sensitive) to represent an ESC character.
- Response sequences of the VT emulator to certain requests (like Device Attributes, or the cursor position) are read automatically and printed to stdout. If the stdout is redirected (e.g. to the underlying pipe of a FOR /F loop, or to a file) the response can easily be captured. Without redirection, the response string shouldn't appear in the terminal window, as this leads to an "ineffective" VT sequence.
- If vt.exe targets the legacy console window, it will fail with errorlevel 1. It's not a bug, it's a feature. You may want to know if VT sequences are supported. So you could work with it like this:
- Use vt.exe once without any argument. Capture the errorlevel, and use it to fork your code into branches, one for VT support and one without VT support. Or ...
- Always use vt.exe only for the escape sequences, and ECHO for the printable strings.
Code: Select all
@echo off &setlocal :: print the help message vt /? :: run vt without argument if you only want to determine if VT processing is supported vt if errorlevel 1 echo The legacy console doesn't support VT processing. :: colored output vt \e[34;107mColored output (containing spaces) ^& "quoted substring"\e[0m\n :: write \N, \E, \n, and \e vt literal \\N, \\E, \\n, and \\e\n :: capture the cursor position (which is at the beginning of the output of the sequence when we request it) set "response=" for /f "delims=" %%i in ('vt \e[6n') do set "response=%%i" if defined response set "response=%response:~2,-1%" for /f "tokens=1* delims=;" %%i in ("%response%") do echo cursor position x=%%j y=%%i pause