Personal website of Martin Tournoij (“arp242”); writing about programming (CV) and various other things.

Working on GoatCounter and moreGitHub Sponsors.

Contact at martin@arp242.net or GitHub.

This page's author

A long time ago when the Unix greybeards were slightly less grey beards everyone was using hardware terminals to talk to some mainframe. Those terminals had wildly different feature sets and ways to implement them, which you needed to know about if you wanted your program to run on more than one type of terminal. Hence systems like terminfo and termcap.

The TeleVideo 955 used \x1b[=5l for bold text, and the IBM 3161 used \x1b4H. Both were introduced in 1985. The TeleVideo 950 from 1980 didn’t support bold text at all.

Today everyone is using software terminal emulators, and they all just implement ANSI escape codes for the common stuff. No one is sending \x1b[=5l or \x1b4H.

Do you still need terminfo? It depends. If you just want to style some text and maybe do some basic cursor operations: probably not. If you want to use more advanced operations or read key input: probably yes. If you want maximum compatibility (there’s probably someone using a hardware Wyse terminal, or SunOS 4 with CDE): absolutely.

Here is a list of terminal escape sequences that should always work on any vaguely modern terminal, where “modern” means “since the mid-90s or so”.

This was generated by looking at every terminfo file I could find with my termfo tool (specifically, termfo find-cap) and occasionally testing some things to verify it works. I don’t care what some spec says; I care about what works.

The escape character is always omitted; so [0m is \x1b[0m.

Graphics

These can be combined in a single sequence by joining with a ;. For example \x1b[1;4m for underlined bold text. These can also be combined with colours; for example \x1b[1;38;2;0;255;0;41m to set bold, foreground colour with true colour, and background colour with 16 colour.

Just using \x1b[1m\x1b[4m also works.

Code Terminfo (short, long) Description
[0m sgr0, exit_attribute_mode Turn off all attributes and colours.
[1m bold, enter_bold_mode Enter bold mode.
[2m dim, enter_dim_mode Enter half-bright mode.[1]
[3m sitm, enter_italics_mode Enter italic mode.[2]
[4m smul, enter_underline_mode Enter underline mode.
[5m blink, enter_blink_mode Enter blinking mode.[3]
[7m rev, enter_reverse_mode Enter reverse video mode.
[8m invis, enter_secure_mode Enter blank mode.[4]
[9m smxx Enter strikeout mode.

Colours are set with setab / set_a_background and setaf / set_a_foreground; the format depends on which colour scheme you want to use.

16-colours

Pretty much everything supports 16 colours, unless explicitly disabled by the user. The exact shade is determined by the terminal.

Escapes as «regular» «bright»:

Foreground Background Colour
[30m [90m [40m [100m black
[31m [91m [41m [101m red
[32m [92m [42m [102m green
[33m [93m [43m [103m yellow
[34m [94m [44m [104m blue
[35m [95m [45m [105m magenta
[36m [96m [46m [106m cyan
[37m [97m [47m [107m white

256-colours

Choose a colour from a pre-defined table of 256 colours. This is supported on almost all current terminal emulators, unless explicitly disabled by the user.

Where «C» is a number from 0 to 255:

[38;5;«C»m   Foreground
[48;5;«C»m   Background

True colours

Use “true” RGB colours; this is supported on almost all current terminal emulators, unless explicitly disabled by the user.

Where «R», «G», «B» are the red, green and blue values as decimal, 0 to 255:

[38;2;«R»;«G»;«B»m   Foreground
[48;2;«R»;«G»;«B»m   Background

Cursor movement

Code Terminfo (short, long) Description
[«R»;«C»H cup, cursor_address Set cursor position to «R», «C».[5]
[«N»A cuu, parm_up_cursor Move «N» lines down.
[«N»B cud, parm_down_cursor Move «N» lines up.
[«N»C cuf, parm_right_cursor Move «N» characters to the right.
[«N»D cub, parm_left_cursor Move «N» characters to the left.
7 sc, save_cursor Save current cursor position.
8 rc, restore_cursor Restore cursor to position of last save_cursor.
[6n u7, user7 Request cursor, returned as \x1b[«R»;«C»R

The «N» can be omitted in the above, in which case it will default to 1. For cup the «R» and/or «C» can be omitted, and will default to 1.

Inserting and deleting text

Code Terminfo (short, long) Description
[J ed, clr_eos Clear from cursor to end of screen.
[K el, clr_eol Clear from cursor to end of line.
[1K el1, clr_bol Clear from cursor to beginning of line.
[«N»M dl, parm_delete_line Delete «N» lines, moving all the lines below up.
[«N»P dch, parm_dch Delete «N» characters, moving all afterwards left.
[«N»L il, parm_insert_line Insert «N» lines, moving all lines below down.
[«N»@ ich, parm_ich Insert «N» characters, moving all after right.

The «N» can be omitted in the above, in which case it will default to 1.

Misc

Code Terminfo (short, long) Description
[?25l civis, cursor_invisible Make cursor invisible.[6]
[?25h cnorm, cursor_normal Make cursor appear normal (undo civis).[7]

Keys

Key input handling is kind of a mess, and this is where I really recommend using a terminfo library if at all possible. This also avoids the whole backspace/delete key confusion (less of an issue today than it used to be, but still exists).

Codes terminfo (short, long) Description
[A OA kcuu1 key_up Arrow up
[B OB kcud1 key_down Arrow down
[C OC kcuf1 key_right Arrow right
[D OD kcub1 key_left Arrow left
[5~ [I kpp key_ppage PageUp
[6~ [G knp key_npage PageDown
[2~ [L kich1 key_ic Insert key
[1~ [H OH [7~ khome key_home Home key
[4~ [F OF [8~ kend key_end End key
[11~ [M [[A OP key_f1 F1
[12~ [N [[B OQ key_f2 F2
[13~ [O [[C OR key_f3 F3
[14~ [P [[D OS key_f4 F4
[15~ [Q [[E key_f5 F5
[17~ [R key_f6 F6
[18~ [S key_f7 F7
[19~ [T key_f8 F8
[20~ [U key_f9 F9
[21~ [V key_f10 F10
[23~ [W key_f11 F11
[24~ [X key_f12 F12
\x7f \b kbs key_backspace Backspace key
\x7f [3~ kdch1 key_dc key_delete Delete key; usually sends [3~, but some send \x7f
\x09 - Tab key
\x0d - Enter key
Elsewhere on the interwebs
Footnotes
  1. Except FreeBSD system console where it’s [30;1m

  2. Not super-widely supported, sometimes displays as reverse. 

  3. Characters can still be copy/pasted. 

  4. Top-left is 1;1 

  5. mtm terminfo doesn’t include the question mark, and Linux console adds another escape (\x1b[?1c). But for both this also works. 

  6. Has [?12l for some, but works without that on all; for FreeBSD terminfo has [=0C but that doesn’t work ([?25h does)