Skip to content

Fix line wrapping issue#21

Open
luismulinari wants to merge 2 commits intofreeall:masterfrom
luismulinari:fix-line-wrapping-bug
Open

Fix line wrapping issue#21
luismulinari wants to merge 2 commits intofreeall:masterfrom
luismulinari:fix-line-wrapping-bug

Conversation

@luismulinari
Copy link

Problem

When output exceeded the terminal width and soft-wrapped across multiple physical lines, the library failed to properly clear previous content on standard terminals (macOS Terminal, iTerm2, gnome-terminal, konsole, xterm). This caused previous iterations to stack vertically and "bleed" upward, overwriting earlier terminal content.

Root Cause

The clearing logic used \x1b[1000D (ANSI escape: move left 1000 columns) to position the cursor at column 0 before clearing each line. However, when text soft-wraps across multiple physical lines (without explicit \n characters), most VT100-compatible terminals treat this as a single logical line spanning multiple rows.

When MOVE_UP (\x1b[1A) is then executed, it moves up one logical line in the terminal's internal buffer, not one physical/visual line. This causes the cursor to jump to incorrect positions, resulting in the wrong lines being cleared.

Why it worked in JetBrains Terminal: JetBrains Terminal treats soft-wrapped content as separate physical lines for cursor movement operations, masking the bug.

Before

before.mov

After

after.mov

Solution

Replace \x1b[1000D with \r (carriage return) for positioning the cursor at column 0:

  • \r is a standard ASCII control character (0x0D) that reliably moves to column 0 of the current physical line
  • Works consistently across all terminal emulators regardless of how they handle soft-wrapped content
  • More universal than ANSI escape sequences (even works on very old terminals)
  • Simpler and more efficient (1 byte vs 6 bytes)

Fixed a bug where multi-line output would fail to clear properly on
standard terminals (macOS Terminal, iTerm2, gnome-terminal, konsole, xterm),
causing previous output to stack and "bleed" upward, overwriting earlier
terminal content. This only occurred when output exceeded terminal width and
soft-wrapped across multiple physical lines.

Root Cause:
The clearing logic used ANSI escape sequence \x1b[1000D (move left 1000
columns) before clearing each line. However, when content soft-wraps across
multiple physical lines without explicit newlines, most VT100-compatible
terminals treat this as a single logical line. The MOVE_UP command (\x1b[1A)
then operates on logical lines rather than physical wrapped lines, causing
the cursor to target wrong screen positions during clearing.

Solution:
Replaced \x1b[1000D (move left 1000 columns) with \r (carriage return) in
the line clearing sequence. Carriage return is a standard ASCII control
character that reliably moves the cursor to column 0 of the current physical
line across all terminal emulators, regardless of soft-wrap behavior.

Also fixed log.clear() to output a newline instead of an empty string,
ensuring the cursor properly moves to a new line after clearing, preventing
the bash prompt from appearing on the same line as cleared content.

Changes:
- Line 27: Replace MOVE_LEFT with \r for universal column 0 positioning
- Line 43: Change log.clear() to output \n for proper cursor positioning

Fixes issues with soft-wrapped line clearing on all standard POSIX terminals.
luismulinari added a commit to Automattic/vip-cli that referenced this pull request Dec 8, 2025
The @wwa/single-line-log package is unmaintained and contains a bug
that causes line clearing to fail when output wraps across multiple
physical terminal lines, resulting in stacked output.

This change vendors the fixed version locally with the fix from
freeall/single-line-log#21, which uses '\r' instead of '\x1b[1000D'
for cursor positioning to ensure consistent behavior across all
terminal emulators.

Changes:
- Remove @wwa/single-line-log dependency
- Add src/lib/cli/single-log-line.ts with MIT license preserved
- Update all imports to use local implementation
- Add string-width@8.1.0 as direct dependency

Related PR:
- freeall/single-line-log#21
luismulinari added a commit to Automattic/vip-cli that referenced this pull request Dec 8, 2025
The @wwa/single-line-log package is unmaintained and contains a bug
that causes line clearing to fail when output wraps across multiple
physical terminal lines, resulting in stacked output.

This change vendors the fixed version locally with the fix from
freeall/single-line-log#21, which uses '\r' instead of '\x1b[1000D'
for cursor positioning to ensure consistent behavior across all
terminal emulators.

Changes:
- Remove @wwa/single-line-log dependency
- Add src/lib/cli/single-log-line.ts with MIT license preserved
- Update all imports to use local implementation
- Add string-width@8.1.0 as direct dependency

Related PR:
- freeall/single-line-log#21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant