An unexpected difference between terminal programs: backward line wrapping

02:00 AM · Sep 29, 2026

A very simple way to present the progress of a parallel operation is to print one '.' for every operation started and then backspace and erase these as each operation finishes. The venerable ping program uses a similar output if you're flood pinging; it prints a '.' for every ping packet sent and then backspaces and erases the '.' when it gets a reply, letting you visually see any packet loss as '.'s build up. However, today I discovered an unexpected difference in how (Unix) terminal programs handle part of this,

If your program prints enough '.'s, it may exceed the line length of the window, wrapping what is one logical line onto a second physical line. When your program then backspaces back to erase these '.'s, some terminal programs stop at the start of the most recent physical line. Let's show some text pictures. Suppose that you start with:

Starting: ................|
...                       |

(Where '|' is the right edge where the physical line wraps.)

If you then try to delete six dots, some terminal programs will only visually delete the three on the second physical line and give you:

Starting: ................|
                          |

Others will wrap the deletion around to the previous physical line, erasing three dots on the first line as well:

Starting: .............   |
                          |

I'm used to this second behavior, which you can call 'backward line wrapping' or apparently reverse wraparound.

In Unix, you can't necessarily test this at the shell prompt in typical shells, because typical shells are using line editing code that actually works using cursor addressing and redisplay of the line, so they handle this internally. Instead, you need to use something that shows the raw tty/pty behavior, such as 'cat >/dev/null'.

For X based terminal emulators that I've tried, xterm, urxvt, kitty, and putty (not technically a terminal emulator but it contains one) all do backward line wrapping (reverse wraparound), as does screen even on things that don't handle this. In Wayland, foot apparently also does backward line wrapping. Konsole, gnome-terminal, everything based on the VTE terminal emulation package (which is the basis for gnome-terminal, xfce4-terminal, and a number of others), alacritty, wezterm, and ghostty all don't do backward line wrapping, although the text actually is erased at the Unix tty input layer (so their visual appearance doesn't match what a program like 'cat' will read from the terminal).

The behavior of VTE-based things is especially odd because a signature feature of VTE is that it understands about logical lines and will re-wrap them if you widen or narrow your terminal window. This re-wrapping continues to happen even if you delete some text, but the moment you hit the left edge of a physical line, VTE usually seems to 'freeze' the state of physical line edges and it won't visually delete further back even if you resize the window wider so it's now all one physical line.

I don't have convenient access to terminal emulators on other platforms, such as Windows or macOS, so I don't know how those behave. I suspect that Putty on Windows also does backward line wrapping given that the Unix version does. Two SSH terminal capable things I tried on iOS don't do backward line wrapping; one is cross-platform to Android and one I believe is iOS specific (and I think is using SwiftTerm as its underlying terminal code).

I don't have access to any physical terminals, so I don't know how they traditionally behave. I wouldn't be surprised if the behavior varies from terminal model to terminal model. The Unix terminfo terminal database doesn't seem to have an explicit capability for this that I could spot, although you could argue that auto_left_margin ('bw') applies because it describes similar behavior for cursor_left (aka 'cub1', which is usually an escape sequence and what's generated by the left cursor key, which I believe is typically ESC [ D.). However, in practice it looks like neither gnome-terminal nor xterm set 'bw' in their terminal information, so it doesn't seem like 'bw' is used for this purpose today.

Update: I'm wrong about what 'cub1' normally is. It's normally a backspace. What 'bw' means is complicated.

Regardless of how physical terminals behave (or behaved), I believe that backward line wrapping is the correct behavior for Unix terminal programs. For typed input and user-typed backspaces (or line kill characters), the Unix tty layer will (eventually) delete all input regardless of whether or not the terminal program shows that. A terminal program should do its best to represent what the Unix tty layer will eventually pass to programs that are reading 'cooked' input from it.

(macOS local terminal windows are basically Unix ttys, so this applies to them too. I don't know how Windows command shells behave; it's possible they don't apply backward line wrapping to either the visuals or the actual input, although it would be odd to do the latter since it sort of traps people.)

PS: You might be wondering why this can be called 'reverse wraparound'. The answer is that in the old days, some terminals were sufficiently basic that they didn't have regular (forward) wraparound. If you printed a line with 81 characters on an 80-character terminal without forward wraparound, the 81st character overprinted the 80th character rather than wrapping around to the next line. This is the terminfo auto_right_margin 'am' capability (as discussed in the 'Basic Capabilities' section), and basically everything you'll ever encounter today has it.

(Interested parties can trawl the Unix terminfo database to try to find (video) terminals without 'am'.)