Skip to content
Key Input & Escape Sequences
step 1/5

Reading — step 1 of 5

Read

~2 min readDisplay & Input

Key Input & Escape Sequences

In raw mode, every keystroke shows up as 1+ bytes on stdin. Simple printable keys are one byte ('a' = 0x61). But arrow keys, function keys, Home/End/Page-Up — these arrive as escape sequences: an ESC (0x1b) followed by [ and a payload.

A condensed map:

BytesKey
0x61a
0x1bEsc (alone — must wait briefly to see if more bytes follow)
0x1b 0x5b 0x41Arrow Up
0x1b 0x5b 0x42Arrow Down
0x1b 0x5b 0x43Arrow Right
0x1b 0x5b 0x44Arrow Left
0x1b 0x5b 0x35 0x7ePage Up
0x1b 0x5b 0x36 0x7ePage Down
0x1b 0x5b 0x33 0x7eDelete
0x1b 0x5b 0x48Home
0x1b 0x5b 0x46End
0x0dEnter (Carriage Return, since we killed ICRNL)
0x7fBackspace (on most modern terms — sometimes 0x08)
0x09Tab
0x01..0x1aCtrl-A .. Ctrl-Z (Ctrl+letter is letter - 'a' + 1)
0x1b 0x78Alt-X (ESC followed by a printable)

The ambiguity: a real ESC press also produces 0x1b. Editors handle this with a short read timeout (10 ms in kilo) — if no more bytes follow ESC, treat it as a standalone Esc. Otherwise read the escape sequence.

Different terminals send slightly different sequences. xterm, screen, tmux, kitty, and Windows Terminal all agree on the basics but differ on shifted/modified keys (Ctrl+Arrow, Shift+F5). For a tutorial editor, the table above is enough. Production editors use the terminfo database or libraries like crossterm to handle the variation.

This lesson asks you to decode the byte sequences into key names. You will recognize the same logic when you read the source of editorReadKey() in kilo, KeyCode::from_bytes in Hecto, or crossterm's event parser.

Reference: xterm Control Sequences, kilo editorReadKey, Hecto chapter 3.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…