fnky / ANSI.md
ANSI Escape Sequences
Standard escape codes are prefixed with Escape :
- Ctrl-Key: ^[
- Octal: \033
- Unicode: \u001b
- Hexadecimal: \x1b
- Decimal: 27
Followed by the command, usually delimited by opening square bracket ( [ ) and optionally followed by arguments and the command itself.
Arguments are delimeted by semi colon ( ; ).
General ASCII Codes
Name | decimal | octal | hex | C-escape | Ctrl-Key | Description |
---|---|---|---|---|---|---|
BEL | 7 | 007 | 0x07 | \a | ^G | Terminal bell |
BS | 8 | 010 | 0x08 | \b | ^H | Backspace |
HT | 9 | 011 | 0x09 | \t | ^I | Horizontal TAB |
LF | 10 | 012 | 0x0A | \n | ^J | Linefeed (newline) |
VT | 11 | 013 | 0x0B | \v | ^K | Vertical TAB |
FF | 12 | 014 | 0x0C | \f | ^L | Formfeed (also: New page NP ) |
CR | 13 | 015 | 0x0D | \r | ^M | Carriage return |
ESC | 27 | 033 | 0x1B | \e * | ^[ | Escape character |
DEL | 127 | 177 | 0x7F | Delete character |
Note: Some control escape sequences, like \e for ESC , are not guaranteed to work in all languages and compilers. It is recommended to use the decimal, octal or hex representation as escape code.
Note: The Ctrl-Key representation is simply associating the non-printable characters from ASCII code 1 with the printable (letter) characters from ASCII code 65 («A»). ASCII code 1 would be ^A (Ctrl-A), while ASCII code 7 (BEL) would be ^G (Ctrl-G). This is a common representation (and input method) and historically comes from one of the VT series of terminals.
ESC Code Sequence | Description |
---|---|
ESC[H | moves cursor to home position (0, 0) |
ESC[ ESC[ | moves cursor to line #, column # |
ESC[#A | moves cursor up # lines |
ESC[#B | moves cursor down # lines |
ESC[#C | moves cursor right # columns |
ESC[#D | moves cursor left # columns |
ESC[#E | moves cursor to beginning of next line, # lines down |
ESC[#F | moves cursor to beginning of previous line, # lines down |
ESC[#G | moves cursor to column # |
ESC[#;#R | reports current cursor line and column |
ESC[s | saves the current cursor position |
ESC[u | restores the cursor to the last saved position |
ESC Code Sequence | Description |
---|---|
ESC[J | clears the screen |
ESC[0J | clears from cursor until end of screen |
ESC[1J | clears from cursor to beginning of screen |
ESC[2J | clears entire screen |
ESC[K | clears the current line |
ESC[0K | clears from cursor to end of line |
ESC[1K | clears from cursor to start of line |
ESC[2K | clears entire line |
Colors / Graphics Mode
ESC Code Sequence | Description |
---|---|
ESC[<. >m | Set graphics mode for cell and onward. |
ESC[0m | reset all modes (styles and colors |
ESC[1m | set bold mode. |
ESC[2m | set dim/faint mode. |
ESC[3m | set italic mode. |
ESC[4m | set underline mode. |
ESC[5m | set blinking mode |
ESC[7m | set inverse/reverse mode |
ESC[8m | set invisible mode |
ESC[9m | set strikethrough mode. |
Note: Some terminals may not support some of the graphic mode sequences listed above.
Most terminals support 8 and 16 colors, as well as 256 (8-bit) colors. These colors are set by the user, but have commonly defined meanings.
Color Name | Foreground Color Code | Background Color Code |
---|---|---|
Black | 30 | 40 |
Red | 31 | 41 |
Green | 32 | 42 |
Yellow | 33 | 43 |
Blue | 34 | 44 |
Magenta | 35 | 45 |
Cyan | 36 | 46 |
White | 37 | 47 |
Reset | 0 | 0 |
Note: the Reset color is the reset code that resets all colors and text effects.
Most terminals, apart from the basic set of 8 colors, also support the «bright» or «bold» colors. These have their own set of codes, mirroring the normal colors, but with an additional ;1 in their codes:
The following escape code tells the terminal to use the given color ID:
ESC Code Sequence | Description |
---|---|
ESC[38;5;$ | Set foreground color. |
ESC[48;5;$ | Set background color. |
Where ID is the color index from 0 to 255 of the color table:
The table starts with the original 16 colors (0-15).
The proceeding 216 colors (16-231) or formed by a 3bpc RGB value offset by 16, packed into a single value.
The final 24 colors (232-255) are grayscale starting from a shade slighly lighter than black, ranging up to shade slightly darker than white.
Some emulators interpret these steps as linear increments ( 256 / 24 ) on all three channels, although some emulators may explicitly define these values.
More modern terminals supports Truecolor (24-bit RGB), which allows you to set foreground and background colors using RGB.
These escape sequences are usually not well documented.
ESC Code Sequence | Description |
---|---|
ESC[38;2; | Set foreground color as RGB. |
ESC[48;2; | Set background color as RGB. |
Note that ;38 and ;48 corresponds to the 16 color sequence and is interpreted by the terminal to set the foreground and background color respectively. Where as ;2 and ;5 sets the color format.
ESC Code Sequence | Description |
---|---|
ESC[= | Changes the screen width or type to the mode specified by value. |
ESC[=0h | 40 x 25 monochrome (text) |
ESC[=1h | 40 x 25 color (text) |
ESC[=2h | 80 x 25 monochrome (text) |
ESC[=3h | 80 x 25 color (text) |
ESC[=4h | 320 x 200 4-color (graphics) |
ESC[=5h | 320 x 200 monochrome (graphics) |
ESC[=6h | 640 x 200 monochrome (graphics) |
ESC[=7h | Enables line wrapping |
ESC[=13h | 320 x 200 color (graphics) |
ESC[=14h | 640 x 200 color (16-color graphics) |
ESC[=15h | 640 x 350 monochrome (2-color graphics) |
ESC[=16h | 640 x 350 color (16-color graphics) |
ESC[=17h | 640 x 480 monochrome (2-color graphics) |
ESC[=18h | 640 x 480 color (16-color graphics) |
ESC[=19h | 320 x 200 color (256-color graphics) |
ESC[= | Resets the mode by using the same values that Set Mode uses, except for 7, which disables line wrapping. The last character in this escape sequence is a lowercase L. |
ESC Code Sequence | Description |
---|---|
ESC[?25l | make cursor invisible |
ESC[?25h | make cursor visible |
ESC[?47l | restore screen |
ESC[?47h | save screen |
Redefines a keyboard key to a specified string.
The parameters for this escape sequence are defined as follows:
code is one or more of the values listed in the following table. These values represent keyboard keys and key combinations. When using these values in a command, you must type the semicolons shown in this table in addition to the semicolons required by the escape sequence. The codes in parentheses are not available on some keyboards. ANSI.SYS will not interpret the codes in parentheses for those keyboards unless you specify the /X switch in the DEVICE command for ANSI.SYS .
string is either the ASCII code for a single character or a string contained in quotation marks. For example, both 65 and «A» can be used to represent an uppercase A.
IMPORTANT: Some of the values in the following table are not valid for all computers. Check your computer’s documentation for values that are different.
Solarian Programmer
My programming ramblings
C Programming — using ANSI escape codes on Windows, macOS and Linux terminals
Posted on April 8, 2019 by Paul
In this article I will show you how to use ANSI escape codes to control the colors of your Terminal, write text at arbitrary positions, erase lines of text or portions of the terminal and move the cursor. The advantage of using ANSI escape codes is that, today, these are available on most operating systems, including Windows, and you don’t need to install third party libraries. These are well suited for simple command line applications. If you need to do complex text graphics check the ncurses library.
You can find all the code examples at the GitHub repo for this article.
There is also a video version of this tutorial:
Let’s start with a simple C example that will print a green text message on your Terminal:
If you build and run the above code, on Linux or macOS, you should see the message Hello, World printed in green. A side effect of the above program is that your Terminal will switch the default text color to green. Let’s remedy the above problem by resetting the colors to the original ones before the program ends:
This is what I see on a macOS machine:
Let’s analyze a bit the ANSI escape code that changes the text color to green, this is made up from a few parts:
We can represent the ESC key in a string in a few ways:
The 32 number from the ANSI escape code is the color code for green.
Originally the ANSI escape codes specified only 8 colors for foreground (the text) from 30 to 37: black, red, green, yellow, blue, magenta, cyan and white. Same colors can be used for the terminal background but these are defined as the numbers from 40 to 47. For example, if you want to set the background to blue and the text color to red you can use this code:
This is what I see on my machine:
As a side note, you can use ANSI escape codes in the Chrome Console window, if you want to change the color of the output text:
If you try one of the above C codes on a Windows 10 machine, you will be able to compile it successfully, but the output will be mangled with non printable characters. This is because the Windows console needs to be programmatically put in ANSI escape mode.
I wrote two simple helper functions to setup the console and restore it before the caller program ends. In short, you need to get the output handle for the console and set ENABLE_VIRTUAL_TERMINAL_PROCESSING. Put the next code in a file named ansi_escapes.c:
You’ll also need the header file ansi_escapes.h:
Let’s modify the C code that writes a red text message on blue background in order to work on Linux, macOS and Windows. I’ve saved the modified code as t1b.c:
You can build the code on Linux and macOS with:
and on Windows, assuming that you are using the Visual Studio command line compiler:
This is what I see on a Windows console:
Let’s also collect the color codes for the foreground and background in an enum in ansi_escapes.h:
If you remember from earlier, we’ve used this ANSI escape code to set the foreground or background color:
You can bright the above colors by using:
for example, to have a bright green text you could use:
There are also ANSI escape codes to clear the screen:
and another ones to clear the current line of text:
We can abstract the above operations in ansi_escapes.c like this:
don’t forget to copy the above functions signatures to ansi_escapes.h if you want to be able to use them.
Another useful group of ANSI escape code is the movement set. You can move relative to the current cursor position up, down, left, right or you can jump to a specific position. I’ve grouped these escape codes in a set of helper functions:
Assuming that you’ve placed the above helper functions in ansi_escapes.h and ansi_escapes.c, let’s write a slightly more complex code. Start by clearing the screen, move the cursor position to (1, 1), set the text color to green, set the background color to yellow, write 3 lines of text, move back to second line, erase it and write another text on the second line, move down three lines, move right 5 positions, change text color to magenta, write something else, move down 1:
Here is what I see on my machine if I run the above code:
There are also ANSI escape codes to save and restore the text cursor position, these are useful you plan to go back later and do some edits:
Let’s also modify the last code example, in order to save the cursor position after writing the second line and instead of moving up, let’s use the restore cursor position. Also, we’ll erase the line to the left instead of erasing the entire line:
Please note that I’ve placed the ANSI escape codes for saving and restoring the cursor position in two new functions saveCursorPosition and restoreCursorPosition
This is what I see on my machine, if I run the above code:
You can also inquire about the current cursor position using:
The problem with the above is that the position will be shown on the Terminal in this format:
If you want to not mess your already printed text, you will need a way to put the stdin stream in a no echo, unbuffered mode, read the cursor position from stdin and parse the string to recover the actual coordinates. Changing the stdin mode requires OS specific code, for example on Posix systems you will use functions from termios.h and on Windows functions from windows.h. The GitHub repo for this article contains a possible implementation for the above with this signature:
As a side note, Windows provides a function to get the cursor position, but you will get the absolute cursor position relative the console buffer and not the relative position to your running code as it is the case for when you use ANSI escape codes.
Let’s use getCursorPosition to get the current cursor position in our last example after the cursor was move 5 positions to the right:
This is what I see on my machine:
If you want to learn more about C99/C11 I would recommend reading 21st Century C: C Tips from the New School by Ben Klemens: