Skip to main content
ansicode

DECAWM ?7 — Auto-wrap mode

Toggle whether the cursor wraps to the next line at the right margin (default: on).

Byte forms

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

\\x1b[\x1b[?7h (enable wrap) \x1b[?7l (disable)
\\033[\033[?7h / \033[?7l
\\e[\e[?7h / \e[?7l
ESC [ESC [ ? 7 h / l
hex1b 5b 3f 37 68 / 6c

Description

DEC Auto-Wrap Mode (DECAWM) — DEC private mode 7, documented in xterm-ctlseqs and in the original VT100 reference manual as one of the earliest DEC modes. The enable byte sequence is \x1b[?7h (the *initial* state on every terminal — auto-wrap is on by default), the disable is \x1b[?7l. With wrap enabled, characters that would print past the rightmost column wrap to column 1 of the next row, scrolling the viewport if the cursor was on the last row. With wrap disabled, the cursor stays glued to the last column and each new character overwrites the previous one in place — useful for status lines and TUIs that draw exactly to the edge without unintentionally scrolling. The "phantom column" behavior is specific to DECAWM-on: when a character is printed *into* the last column, the cursor is left in a deferred state (visible at column N, but the next write triggers the wrap rather than overwriting), giving the terminal one extra column of capacity before scrolling — this is the source of countless TUI off-by-one bugs.

The portability surface is unusually consistent across emulators because DECAWM is one of the oldest DEC modes — Linux console / fbcon implements it, ConPTY 1809+ forwards it (legacy cmd.exe pre-ConPTY treats ?7l as a no-op and always wraps), Apple Terminal.app / iTerm2 / kitty / alacritty / wezterm / gnome-terminal / Konsole / Ghostty / Windows Terminal all implement both states. The catch is the wrap-at-eol-confusion pitfall: many TUI libraries that track cursor position client-side will *predict* the wrap one column before the terminal actually does it (because of the phantom-column behavior above), and disagree with the terminal about where the cursor sits — this manifests as drawn characters appearing one row off, particularly visible at the bottom-right corner of full-screen TUIs. The fix in client TUI code is to either query the cursor position via DSR \x1b[6n after the offending write, or to set ?7l for the duration of edge-precise drawing and rely on explicit positioning. tmux honors DECAWM per-pane; screen 4.x and 5.0 honor it but the per-window state does not always round-trip across detach / reattach if the outer terminal resized in between.

Disable with \x1b[?7l, restore with \x1b[?7h. Always restore before yielding the terminal back to the user — otherwise the user's shell prompt and command-line editor will behave erratically (long lines visibly truncated, readline cursor calculations diverging from displayed position). The robust pattern is XTSAVE / XTRESTORE (\x1b[?7s / \x1b[?7r) so the state on exit matches whatever the parent had, rather than unconditionally on. DECAWM also interacts with DECOM (?6 — origin mode, governs whether the cursor coordinate frame is the full screen or the scroll region) and DECSTBM (CSI r — set scrollable margins): wrap-on-the-edge wraps within the *scroll region* if DECOM is also active. Related: alt-screen (TUIs typically toggle ?7l after entering alt-screen for edge-precise drawing), cursor-position (CUP — the alternative to client-side position prediction when the phantom column trips you up), dec-origin-mode (the DECOM mode that combines with DECAWM to define the actual wrap boundary).

Spec citation: xterm-ctlseqs (DEC Private Mode 7, DECAWM)

Examples

bash
printf '\033[?7l'   # disable wrap for status bar\nprintf '\033[?7h'   # restore
python
import sys; sys.stdout.write('\x1b[?7l')
go
fmt.Print("\x1b[?7l")
javascript
process.stdout.write('\x1b[?7l')
c
printf("\x1b[?7l");

Used in

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

  • cat, less long-line behaviourwith DECAWM on (`\x1b[?7h`, default) long lines wrap at the right margin; `less -S` toggles a horizontal-scroll mode that effectively requires DECAWM off semantics for the visible line
  • vim, neovim `:set wrap` / `:set nowrap``textwidth` and `wrap` interact with DECAWM — `nowrap` relies on the terminal's DECAWM-off behaviour at the right margin so the editor's own horizontal scroll takes over
  • tput rmam / tput smam`tput rmam` emits `\x1b[?7l` (auto-margin off / DECAWM reset), `tput smam` emits `\x1b[?7h` — used by curses-based scripts that draw fixed-width tables and don't want a stray glyph at column N triggering implicit wrap
  • column, pr, fmt fixed-width outputcolumn-aligned output assumes DECAWM is on (default) and that the terminal honours the right-margin wrap — overflowing rows degrade gracefully into a new line rather than truncating
  • GNU readline / bash line-editingreadline tracks DECAWM state to compute the prompt's wrap point; getting it wrong makes the cursor land on the wrong row after a wrap (the classic `\[ \]` PS1 escape bug stems from this)

Frequently asked

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

Why do TUI columns sometimes appear shifted by one when DECAWM is enabled?
It's the *phantom column*. With ?7h (the default), writing a character into the last column does NOT immediately wrap — instead the terminal leaves the cursor in a deferred state where the *next* write triggers the wrap. The visible cursor sits at column N, but the next character lands on column 1 of the next row. TUI libraries that track cursor position client-side often predict the wrap one column early and disagree with the terminal about where the cursor actually is. The fix is either (a) query DSR \x1b[6n (see csi-dsr) after writes that approach the right margin, or (b) toggle ?7l for the duration of edge-precise drawing and rely on CUP for positioning, then restore ?7h before yielding control.
Is \x1b[?7l safe to leave set when my program exits?
No — never leave wrap-off as the exit state. The user's shell prompt, readline-based command editor, and less / man will all behave badly: long input lines visually truncate at the right margin while the readline cursor calculation keeps advancing, producing the classic "typing falls off the screen" symptom. Always restore \x1b[?7h (or use the XTSAVE / XTRESTORE pair \x1b[?7s / \x1b[?7r to round-trip whatever state the parent had) in your terminal-restore atexit / signal handler. The robust pattern: save at startup with \x1b[?7s, set \x1b[?7l for the duration, restore with \x1b[?7r on exit — including SIGINT, SIGTERM, and crash paths. Pairs naturally with restoring ?25 (cursor visibility), ?1049 (alt-screen), and ?1000+ (mouse modes) — the full TUI-exit hygiene checklist.

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