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[?7h (enable wrap) \x1b[?7l (disable)\033[?7h / \033[?7l\e[?7h / \e[?7lESC [ ? 7 h / l1b 5b 3f 37 68 / 6cDescription
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
printf '\033[?7l' # disable wrap for status bar\nprintf '\033[?7h' # restoreimport sys; sys.stdout.write('\x1b[?7l')fmt.Print("\x1b[?7l")process.stdout.write('\x1b[?7l')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(seecsi-dsr) after writes that approach the right margin, or (b) toggle?7lfor the duration of edge-precise drawing and rely on CUP for positioning, then restore?7hbefore yielding control. - Is
\x1b[?7lsafe 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/manwill 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[?7rto 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[?7lfor the duration, restore with\x1b[?7ron 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
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | yes | yes | yes | yes | partial | yes | yes | yes | yes | yes | yes | yes | yes |