DECSET ?12 — Cursor blink
Enable or disable the blinking attribute of the cursor — independent of cursor shape.
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[?12h (start blinking) \x1b[?12l (stop blinking)\033[?12h / \033[?12l\e[?12h / \e[?12lESC [ ? 1 2 h / l1b 5b 3f 31 32 68 / 6cDescription
Toggle the cursor-blink attribute. Distinct from DECSCUSR (\x1b[N SP q), which combines shape AND blink in one parameter: with ?12 you can keep the user's preferred shape (block / bar / underline) and just override whether it blinks. Used by editors that want a steady cursor in normal mode and a blinking one in insert mode WITHOUT touching the user's chosen shape. Reset to terminal default by combining with DECSCUSR \x1b[0 q or DECSTR (\x1b[!p).
Spec citation: xterm-ctlseqs (Private mode 12)
Examples
printf '\033[?12h' # start blinking\nprintf '\033[?12l' # stop blinkingimport sys; sys.stdout.write('\x1b[?12l')fmt.Print("\x1b[?12l")process.stdout.write('\x1b[?12l')printf("\x1b[?12l");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- vim / neovim `'guicursor'` per-mode blinkvim's `:set guicursor=n-v-c:block-Cursor/lCursor-blinkwait300-blinkon200-blinkoff150,i-ci:ver25-iCursor` emits `\x1b[?12h` on insert-mode entry and `\x1b[?12l` on insert-mode exit — keeps the user's preferred block / bar / underline shape (set via DECSCUSR) while toggling only the blink. neovim ≥ 0.5 honours the same syntax
- helix editor `cursor-shape` blink modeshelix's `[editor.cursor-shape]` config (`insert = "bar"`, `normal = "block"`) plus `[editor] cursor-blink = true` emits `\x1b[?12h` on focus-gain and `\x1b[?12l` on focus-loss — distinct from kakoune's all-or-nothing approach. Verified by `script -q -c hx /dev/null` and grep-ing `\x1b\[?12`
- kitty `cursor_blink_interval` configkitty's `cursor_blink_interval 0.5` in `~/.config/kitty/kitty.conf` is enforced *terminal-side* — but apps that emit `\x1b[?12l` (e.g. midnight commander, htop) can override per-application; kitty respects DECSET ?12 from the running process even when the user config sets a non-zero blink. Setting the interval to `0` disables blinking globally
- Alacritty `cursor.style.blinking` profileAlacritty's `cursor.style.blinking = "On"` in `alacritty.toml` honours `\x1b[?12h` / `\x1b[?12l` from running apps — apps overriding the user's choice for a brief insert-mode flash, then restoring. `cursor.blink_interval = 750` (default) sets the period when blink is active
- midnight commander (mc) cursor-blink suppressionGNU `mc` emits `\x1b[?12l` on launch and `\x1b[?12h` on exit to suppress blink while the user is in its TUI panels — visible by `script -c 'mc' /dev/null; grep -a '\x1b\[?12' typescript`. Same pattern in `ranger`, `nnn`, `lf` (each shipping a `cursor.blink = false` config knob that translates to the byte sequence)
Frequently asked
Short answers to the questions developers actually search for this sequence.
- How do I turn off cursor blinking —
\x1b[?12lor DECSCUSR\x1b[<n> q? - Two distinct mechanisms exist, and which one works depends on the terminal.
\x1b[?12l(ATT 610 DEC private mode) is the old xterm-compatible toggle for *just* the blink attribute — supported by xterm, foot, gnome-terminal, konsole; unsupported on macOS Terminal and Windows Terminal (silently ignored). DECSCUSR\x1b[<n> q(with evennfor non-blinking, odd for blinking — 0/1=blinking block, 2=steady block, 3=blinking underline, 4=steady underline, 5=blinking bar, 6=steady bar) is the modern path supported almost everywhere (xterm, kitty, alacritty, wezterm, ghostty, foot, Windows Terminal, iTerm2, gnome-terminal, konsole). For broadest compatibility emit DECSCUSR with the desired even value (e.g.\x1b[2 qfor steady block); for old terminals that only honour?12, also send\x1b[?12l. They don't conflict. - Why does setting cursor-blink in my TUI leak across into the user's shell?
- Both
?12and DECSCUSR persist across process exit by design — the terminal has no concept of "reset on PID death". You must explicitly restore the prior state in an atexit /defer/trap EXIThandler. The portable restore is\x1b[0 q(DECSCUSR parameter 0 = terminal default — block + whichever blink the user configured), which works on every terminal supporting DECSCUSR. For paranoid round-trip safety, query DECRQSS at startup with\x1bP$q q\x1b\\to capture the exactnvalue, save it, and emit\x1b[<saved> qon exit. Common bug: setting\x1b[5 q(blinking bar) for an editor caret, crashing, and leaving the user'sbashprompt blinking — survives until they emit a manual reset or restart the terminal.
Terminal support
- xterm
- yes
- Linux console (fbcon)
- partial
- macOS Terminal.app
- partial
- iTerm2
- yes
- Windows Terminal
- yes
- cmd.exe / ConPTY
- partial
- kitty
- yes
- alacritty
- yes
- WezTerm
- yes
- Ghostty
- yes
- GNOME Terminal
- yes
- Konsole
- yes
- tmux
- yes
- GNU screen
- yes
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | partial | partial | yes | yes | partial | yes | yes | yes | yes | yes | yes | yes | yes |