DECSCUSR — Cursor shape
Change the cursor shape: block, underline, or bar (with optional blink).
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[N\x20q (N = 0..6)\033[1 q\e[1 qESC [ N SP q1b 5b <N> 20 71Description
DEC Set Cursor Style (DECSCUSR). Standard CSI with a SPACE (0x20) intermediate byte before the final q (0x71): \x1b[<N>\x20q. The parameter encodes both shape *and* blink in a single value — 0 = restore user default, 1 = blinking block (factory default), 2 = steady block, 3 = blinking underline, 4 = steady underline, 5 = blinking bar (vertical line), 6 = steady bar. First shipped in xterm patch 282 (Sep 2013); later adopted by every modern GUI emulator. The canonical editor-mode pattern: vim sets \x1b[6\x20q (bar) for insert mode and \x1b[2\x20q (block) for normal mode via its t_SI / t_EI terminal-string options; many shells (fish, zsh-vi-mode) do the same for vi command-line editing.
Portability — xterm, iTerm2, kitty, alacritty, wezterm, gnome-terminal, Konsole, Ghostty, Windows Terminal, ConPTY 1809+ all support DECSCUSR fully. Linux console is partial (the framebuffer driver honours shape changes but ignores the blink bit on most distros). Windows legacy cmd.exe is partial — pre-ConPTY ignored it; ConPTY forwards it. Apple Terminal.app added support late but works. The biggest authoring stumble is the SPACE intermediate byte: \x1b[6q (no space) is *not* DECSCUSR — without the SP intermediate the final q parses as a different (often DECSTBM-related) sequence and the cursor doesn't change at all. The byte sequence must be exactly ESC [ <N> SPACE q. terminfo capability Ss (set cursor style) is defined for DECSCUSR but most terminfo entries don't populate it, so apps tend to hard-code the byte sequence directly. tmux forwards DECSCUSR to the outer terminal correctly across modern versions.
Restore-on-exit is the durable cleanup. A crashed editor that never restored the user's preferred shape leaves the terminal stuck on whatever bar / underline DECSCUSR last set — surprising the user when they return to the shell prompt. The canonical cleanup is \x1b[0\x20q (parameter 0 = "restore user default") on exit, typically wired into the editor's t_EI or an atexit handler. The heavier hammer is DECSTR (\x1b[!p, see decstr-soft-reset) which resets DECSCUSR among other private modes without clearing the scrollback. Be aware that "user default" is terminal-defined — most emulators map parameter 0 to blinking block, but kitty / wezterm / iTerm2 honour a user-configured default, so the same \x1b[0\x20q can produce different shapes on different terminals — that's intended behaviour, not a bug. Related: cursor-visibility (DECTCEM ?25 — orthogonal: visibility vs shape, both need cleanup on crash), cursor-position (CUP — placement, the third cursor concern), dec-cursor-blink (DECSET ?12 — blink-only toggle that doesn't disturb the chosen shape, the alternative when you want to override blink without forcing a specific shape).
Spec citation: xterm-ctlseqs (DECSCUSR, CSI Ps SP q)
Parameters
| 0 | user-default cursor |
| 1 | blinking block |
| 2 | steady block |
| 3 | blinking underline |
| 4 | steady underline |
| 5 | blinking bar |
| 6 | steady bar |
Examples
printf '\033[6 q' # vertical bar (insert mode)\nprintf '\033[2 q' # block (normal mode)\nprintf '\033[0 q' # restore defaultimport sys; sys.stdout.write('\x1b[6 q')fmt.Print("\x1b[6 q")process.stdout.write('\x1b[6 q')printf("\x1b[6 q");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- vim, neovim`guicursor` writes DECSCUSR per mode — block for normal, vertical bar for insert, underline for replace
- fishdefault `fish_vi_cursor` swaps cursor shape on vi-mode transitions
- zsh + zsh-vi-mode pluginblock on NORMAL, bar on INSERT — emitted from the line-init hook
- bash with `bind 'set show-mode-in-prompt on'`vi-mode aware prompts emit DECSCUSR when switching command/insert
- starship — `vicmd_symbol` companion that also sets cursor shape
Frequently asked
Short answers to the questions developers actually search for this sequence.
- Why does
\x1b[6qnot change my cursor shape — but\x1b[6 qdoes? - DECSCUSR requires a SPACE (0x20) *intermediate* byte before the final
q: the wire form is exactly ESC[<N>SPACEq. Without the space,\x1b[6qparses as a different (DECSTBM-related) CSI and the cursor doesn't change at all. In\e-quoted shell strings remember the space —printf '\e[6 q'is correct,printf '\e[6q'is silently wrong. - Why does my cursor stay as a block after vim exits, instead of going back to a bar?
- vim configures the cursor shape via
t_SI/t_EIfor *its own* insert / normal modes but doesn't restore the user's pre-vim shape on exit unlesst_teis set to emit\x1b[0\x20q(DECSCUSR 0 = restore terminal default). Addlet &t_EI = "\e[2 q" | let &t_te ..= "\e[0 q"to your.vimrc, or send\x1b[0\x20qfrom your prompt to repaint each new line. neovim handles this correctly out of the box since 0.4.
Terminal support
- xterm
- yes
- Linux console (fbcon)
- partial
- macOS Terminal.app
- yes
- 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 | yes | yes | yes | partial | yes | yes | yes | yes | yes | yes | yes | yes |
Related sequences
In the family cookbook
CSI cookbook · 6. Insert / delete / cursor shape — IL / DL / ICH / DCH / ECH + DECSCUSR