Skip to main content
ansicode
OSC (terminal control)

OSC escape codes — window title, hyperlinks, colour palette

Operating System Command. The `ESC ] n ; payload BEL` (or `ESC \` terminated) family — window / icon title, the OSC 8 hyperlink protocol, dynamic colour queries, palette overrides, working-directory reporting. The protocol layer that lets terminals talk back to and configure the emulator itself.

20 sequences

OSC cookbook — driving the terminal chrome with six recipes

OSC sits one layer outside CSI — instead of painting glyphs in the grid, OSC drives the terminal's surrounding chrome: window title, hyperlinks, the colour palette itself, shell-integration markers, inline images, progress bars. Six stops cover the envelope syntax, window/tab titles as the canonical example, the OSC 8 hyperlink protocol, palette overrides, the FinalTerm OSC 133 prompt marks that turn a flat byte stream into structured blocks, and the OSC 1337 + OSC 9;4 codes that talk to the host OS's taskbar.

  1. 1. The envelope — \x1b]\x07 or \x1b\\

    Every OSC sequence is \x1b] (ESC ]), a numeric Ps (0, 8, 133, etc.), then ;-separated payload, then a terminator. Two terminators are both valid: \x07 (BEL — xterm's original de-facto choice, one byte) and \x1b\\ (ST — ECMA-48 standards-correct, two bytes spelt ESC \). Modern emulators accept both; reach for BEL on a one-shot shell printf, reach for ST when you're nesting OSC inside DCS or tmux pass-through where BEL would mean something else. There's also an 8-bit C1 form \x9d … \x9c you'll see in old VT manuals but never in the wild. **Always emit the terminator** — a missing BEL/ST hangs the parser until the next byte that happens to be one, so the next stray ^G in your output silently closes your OSC and treats everything past it as text.

  2. 2. Window & tab titles — OSC 0 / 1 / 2

    The canonical OSC sequence: \x1b]0;TITLE\x07 sets both the window title bar and the icon name (taskbar text on Windows, dock-icon hover text on macOS). Sub-codes split the two: OSC 1 icon name only, OSC 2 window title only — useful when your shell wants the window title to stay pinned to the project while the icon flashes an attention-state. The common shell idiom wires it into PROMPT_COMMAND / precmd: printf '\033]0;%s — %s\007' "$USER@$HOST" "$(basename "$PWD")" redraws the title every prompt with the current directory. Inside tmux / screen the inner OSC needs the \ePtmux;\e DCS wrapper or it won't reach the outer terminal — tmux's set-option -g set-titles on does the wrapping for you. Supported everywhere except the bare Linux console (no chrome to set).

  3. 4. Palette overrides — OSC 4 / 10 / 11 / 104

    Four codes let you repaint the palette itself rather than picking from it. \x1b]4;n;rgb:RR/GG/BB\x1b\\ overrides slot n (0–255) of the xterm 256-palette for this session — so \e]4;1;rgb:e0/3a/3a\e\\ retunes the red that \x1b[31m will use from then on. OSC 10 and OSC 11 change the default foreground and default background colours independent of the indexed palette — handy for a TUI to dim the chrome behind a modal without touching any text colour. The matching reset is \x1b]104;n\x1b\\ (revert one slot to compiled-in default) or bare \x1b]104\x1b\\ to revert every slot at once; OSC 110 / OSC 111 (no args) reset default fg / bg respectively. The colour string accepts the X11 rgb:RRRR/GGGG/BBBB long form too, plus #rrggbb on most emulators.

  4. 5. Shell prompt marks — OSC 133 (FinalTerm A / B / C / D)

    FinalTerm's OSC 133 turns a shell session from a flat byte stream into structured blocks the terminal can navigate. Four codes mark boundaries: \x1b]133;A\x07 before the prompt, \x1b]133;B\x07 between prompt and user input, \x1b]133;C\x07 between Enter and the command's stdout, \x1b]133;D;<exit>\x07 after the command exits (exit code optional). Kitty, iTerm2, WezTerm, Ghostty, Warp, and VS Code's terminal then expose UX you can't fake otherwise: jump to previous / next prompt with a keystroke, fold a single command's output, decorate the gutter with red-triangle / green-tick based on exit code, scroll one command at a time. Wire it into your PS1 + preexec + precmd hooks (atuin, starship, and the emulator-bundled scripts do it for you). Pair with \x1b]7;file://host/path\x1b\\ (OSC 7, cwd advertising) so the terminal also knows where each block ran — together they're the full shell-integration story.

  5. 6. Inline images & progress — OSC 1337 and OSC 9 ; 4

    Two out-of-band OSC codes drive the host OS's window chrome rather than painting glyphs. **\x1b]1337;File=name=<b64>;inline=1:<b64-payload>\x07** is iTerm2's inline-image protocol — the same vocabulary covers PNG, JPEG, animated GIF, PDF — and is the path the imgcat shell script uses (iTerm2 ships it; WezTerm and Konsole 22.04+ implement the File= subset). The same OSC 1337 envelope also carries non-File subcodes (SetUserVar, SetMark, ReportCellSize) for status-bar variables, navigation marks, and pixel-accurate Sixel sizing. **\x1b]9;4;<state>;<pct>\x07** is the ConEmu progress protocol Windows Terminal 1.18+ standardised — state=1 normal, 2 error, 3 indeterminate, 4 paused, 0 clear — and the terminal forwards it to the OS taskbar (WT) or tab indicator (Ghostty, WezTerm). Don't confuse it with iTerm2's OSC 9 ; <message> notification: the ;4 second token is the disambiguator, so always emit the full shape. Both are safe to emit unconditionally — unsupported emulators silently drop the bytes.

All sequences in this family

Browse other families