Skip to content

fix: wrap composer input across multiple lines#2

Open
dsilbergleithcu-godaddy wants to merge 1 commit intominghinmatthewlam:mainfrom
dsilbergleithcu-godaddy:fix/input-wrap
Open

fix: wrap composer input across multiple lines#2
dsilbergleithcu-godaddy wants to merge 1 commit intominghinmatthewlam:mainfrom
dsilbergleithcu-godaddy:fix/input-wrap

Conversation

@dsilbergleithcu-godaddy
Copy link
Copy Markdown

Summary

Fixes #1. In Read Mode, typing past the terminal width truncated the input and hid the cursor. The composer now wraps onto additional visual rows and the footer grows to accommodate it.

Changes

  • wrapInput(text, cursor, wrapWidth) — character-based wrap that also reports (cursorRow, cursorCol). Handles the two awkward cases:
    • cursor sitting exactly on a wrap boundary → next line, col 0
    • cursor at end of a full-width last line → fresh empty trailing line
  • Dynamic footer — replaced fixed FOOTER_LINES = 5 with FOOTER_STATIC_LINES = 4 + inputVisualLines. vh() / maxScroll() now reflect the real viewport so PgUp/PgDn still page correctly.
  • Continuation indent — wrapped rows start with two spaces so they line up under the > prompt.
  • Render order: the input is wrapped before vh() is read, so the viewport/footer split is correct on the same frame the input grows or shrinks.

I went with character-based wrap rather than word-boundary wrap. It makes cursor mapping exact for any input (including paste, long URLs, CJK) and avoids edge cases around whitespace-only segments. Happy to add word-boundary wrapping on top if you'd prefer — the hooks are all in one function.

Tests

Added test/wrap-input.test.ts with 9 focused tests (one assertion each) covering: short text, exact width, long wrap, cursor at start, cursor mid-line, cursor at wrap boundary, cursor at end of full text, cursor at end of partial line, empty text. I also did a break-the-code check (inverted the wrap condition) and confirmed 3/9 failed before restoring.

Run: npx tsx --test test/wrap-input.test.ts

Not covered

  • Composer that wraps taller than the terminal itself — content clips at the bottom edge. Could be addressed in a follow-up by scrolling the composer independently.
  • Word-boundary breaking — intentionally omitted; see summary.

When a user typed past the terminal width in Read Mode, the input was
truncated and the cursor became invisible. The composer now wraps to
additional visual rows and the footer grows to fit.

- Add wrapInput() that wraps at character boundaries and reports
  cursorRow/cursorCol, handling the wrap-width boundary and trailing
  empty-line cases.
- Replace fixed FOOTER_LINES=5 with dynamic inputVisualLines so vh()
  and maxScroll() account for the composer's real height.
- Continuation lines get a 2-space indent to align with '> '.
- Add focused tests for wrap behavior and cursor placement.

Fixes minghinmatthewlam#1
@dsilbergleithcu-godaddy dsilbergleithcu-godaddy marked this pull request as ready for review April 23, 2026 23:04
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.

Input text does not wrap to next line

1 participant