Skip to main content
ansicode

CBT — Cursor Backward Tabulation (CSI Z)

Move the cursor back N tab stops — the reverse of pressing Tab.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b[NZ
\\033[\033[1Z
\\e[\e[1Z
ESC [ESC [ N Z
hex1b 5b <N> 5a

Description

Cursor Backward Tabulation. Final byte Z (0x5a) moves the cursor backward to the previous tab stop, repeated N times (default 1 if the parameter is omitted). It is the mirror of CHT (CSI Ps I) and the moral opposite of pressing the Tab key (HT, 0x09). If the cursor is already at column 1 or before the first remaining tab stop, it stays put. Default tab stops live every 8 columns unless the application has cleared or shifted them with TBC (\x1b[Ng) and HTS (\x1bH). CBT is rarely emitted by humans, but matters for terminfo capability cbt and for any TUI replaying recorded keystrokes (Shift-Tab in form fields, etc.).

Spec citation: ECMA-48 §8.3.7 (CBT)

Examples

bash
printf 'a\tb\tc\033[2Z|'   # cursor jumps back 2 tab stops, then writes |
python
import sys; sys.stdout.write('\x1b[2Z')
go
fmt.Print("\x1b[2Z")
javascript
process.stdout.write('\x1b[2Z')
c
printf("\x1b[2Z");

Used in

Real-world tools that emit this sequence — anchors the bytes to commands you've already used.

  • vim / neovim Shift-Tab in insert mode (`:imap <S-Tab>`)vim's default `<S-Tab>` insert-mode binding emits `\x1b[Z` to dedent by one `shiftwidth` — visible with `:set verbose=15` while pressing Shift-Tab on an indented line. `:set softtabstop=0` flips the behaviour to a literal CBT pass-through, useful in Makefile recipes
  • readline `menu-complete-backward` (Shift-Tab in bash)GNU readline's `menu-complete-backward` widget — bound to `"\e[Z"` (CBT) by default in bash 4.3+ — cycles candidates in reverse without emitting CBT to the terminal itself; the binding *consumes* the keypress and updates the line editor
  • fzf `--bind shift-tab:toggle+up`fzf treats `\x1b[Z` as `shift-tab` and routes it to its widget table — used in `~/.fzf.bash` recipes that bind Shift-Tab to toggle-multi-select with cursor-up in one keystroke. Same code path in skim and zoxide's fuzzy picker
  • ncurses form library navigationform fields rendered by ncurses' `<form.h>` use `\x1b[Z` for backward field navigation — `form_driver(form, REQ_PREV_FIELD)` internally maps to CBT emission when the form is in its default tab-driven mode. Visible in nmtui, alpine config dialogs
  • terminfo `cbt` cap (queryable via `tput cbt`)`tput cbt` looks up the `cbt` capability and emits the terminal-specific CBT byte sequence — `xterm-256color`, `screen-256color`, `tmux-256color` all map to `\x1b[Z`. Useful in shell scripts that need a portable Shift-Tab emission without hardcoding the bytes

Frequently asked

Short answers to the questions developers actually search for this sequence.

What does CBT (\x1b[Z) do that Backspace doesn't?
CBT moves the cursor backward to the previous *tab stop*; Backspace (BS, \x08) moves backward by exactly one column. With the default 8-column grid and the cursor at column 17, \x1b[Z lands at column 9 in one step, whereas BS would take 8 emissions. CBT is the parameterized inverse of HT (\t) and the mirror of CHT (\x1b[I), see csi-cht. If the cursor is already on or before the first remaining tab stop, CBT is a no-op — it never crosses column 1. Tab stops are themselves controlled by HTS (\x1bH, see esc-hts) and TBC (\x1b[g / \x1b[3g, see csi-tbc), so a custom layout changes where CBT lands.
Why does \x1b[Z sometimes do nothing in my terminal?
Three common causes. (1) The cursor is already at column 1 — CBT clamps and reports no movement. (2) The application or a prior \x1b[3g (TBC clear-all, see csi-tbc) wiped every tab stop, so there's nothing to retreat to and CBT is a no-op. (3) You're inside pre-ConPTY cmd.exe, which advertises partial CSI support and silently drops uncommon final bytes like Z — modern Windows Terminal handles it correctly. Verify with DSR \x1b[6n (see csi-dsr) before and after the CBT to see whether the column number actually changed.

Terminal support

xterm
yes
Linux console (fbcon)
yes
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

Related sequences

In the family cookbook

C0 cookbook · 3. HT — horizontal tab and the TBC / HTS lineage