Skip to content

v0.21 bugs: wrapped-row redraws (#388), command colors after a slow zshrc, width in /modules explain (#365) - #423

Merged
raiseCatError merged 7 commits into
devfrom
fix/v021-bugs
Oct 18, 2026
Merged

raiseCatError merged 7 commits into
devfrom
fix/v021-bugs

Conversation

@raiseCatError

Copy link
Copy Markdown
Owner

Stacked on #422. Bug fixes from the v0.21 stabilization review of every open type:bug issue, plus two defects found while verifying them.

#388: a redraw over a wrapped line erased earlier output

The live region (#412) moved the cursor by stored (logical) lines, but programs count terminal rows. At 40 columns, a progress display whose line wraps to two rows moved up three rows. NMSh moved up three lines, and CSI J erased the program's own log lines above it, one more per frame. Reproduced in the parser, in a real zsh PTY at 40 columns, and through the frontend.

  • The frontend reports the PTY's width. Wrapped lines occupy their rows: vertical moves, ESC M/D/E and line feed move by rows. CR, BS, CSI G/C/D and CSI K act on the cursor's row. The pending wrap after an exactly-filled row is tracked. A resize re-wraps.
  • The deliberately limited contract is now explicit and tested. Absolute rows (CSI H/f/d) are not mapped, because an inline program cannot know its rows (cursor position reports aren't answered). Scroll regions aren't emulated, except that text drawn below a region the program set (an installer's status row) is not stored, so it can't leak into log rows.
  • 6 new tests (parser, real PTY, frontend at 40 columns). All fail on the previous parser; the frontend one also fails without the width wiring.

Command colors stopped for the session after a slow .zshrc (found verifying #408)

The semantic helper reads lookups only after sourcing the user's configuration, but each lookup's 1.5 s limit started when it was sent. A 2 s configuration (nvm, a large framework) made the first lookup time out, which killed the helper: every later executable or builtin stayed uncolored. Lookups are now timed from when the helper reads them, and startup has its own 20 s bound. The test fails on the old service. #408's own generation/re-ask synchronization was re-checked and holds.

#365: why a module isn't shown, including width

The Context Rail and Status Strip record how their width fitting treated routed modules in the last live frame. /modules explain adds "left out for width in the last frame" or "shortened to fit". Previews never overwrite the record. The Main Prompt and Right Context truncate text rather than drop modules; a per-segment trace there is documented as future work.

Investigated, not reproducible

Also checked: 99 adversarial input/recognizer combinations for Semantic Output (up to a 2 MB single line). None exceeded 150 ms.

Refs #388, #408, #365, #356, #403, #410

…ever erases earlier output

The live region (#412) moved the cursor by stored lines. Stored lines are logical,
but programs count terminal rows: a progress display whose line is wider than the
window (two rows at 40 columns) moved up three rows to redraw itself, NMSh moved up
three lines, and `CSI J` erased the program's own log lines above the display, one
more per frame. Reproduced in the parser, in a real zsh PTY at 40 columns, and
through the frontend; the new tests fail on the previous parser.

- The frontend reports the PTY's width (setScreenColumns). A line wider than it
  occupies several rows: cursor up/down, `ESC M/D/E` and line feed move by rows
  (the next row of a wrapped line, or the next line), within the same bounds.
- Carriage return, backspace, `CSI G/C/D` and `CSI K` act on the cursor's row within
  its line; erasing never removes the row the cursor is on. The pending wrap after
  a row is filled exactly is tracked from the character that filled it.
- A resize re-wraps stored lines at the new width, as a reflowing terminal does.
- The contract stays deliberately limited and is now explicit and tested: absolute
  rows (`CSI H/f/d`) are not mapped (no cursor position reports are answered, so an
  inline program cannot know its rows); scroll regions are not emulated, except
  that text drawn below a region the program set (an installer's reserved status
  row) is not stored, so it cannot leak into the log rows. NMSh's own lines are
  never dropped.
- Unknown width keeps the previous line-based behavior.

Refs #388
…om when the helper reads them

Found while re-verifying #408. The semantic helper (a zsh that sources the user's
configuration and answers `whence` lookups) reads requests only after its startup
files finish, but each lookup's 1.5 s limit started when it was sent. A
configuration that takes longer to load (nvm, a large framework: 2 s reproduced)
made the first lookup time out, which ends the helper; every later executable or
builtin then stayed uncolored (neither known nor unknown) for the whole session.

The helper now says when it reads requests; lookup limits (and raw source/facts
lookups) start then, and startup itself has its own 20 s bound. The new test (a 2 s
.zshrc) fails on the old service: `ls` came back unknown after 1.5 s and the helper
was dead.

#408's own synchronization was re-checked: newer shell knowledge bumps the
generation and clears pending lookups, so a late answer finds no pending entry and
is never cached; superseded lookups ask again (at most three times).

Refs #408
…ortened it, for width (#365)

#365 asks why a module is visible, hidden or compacted. Explain covered routing,
visibility, conditions and source state; width was missing. The Context Rail fits
module groups by priority (place, compact, then drop) and the Status Strip narrows
forms, then drops the lowest priorities; both now fill an optional fit report on
their live render (previews of a draft never overwrite it), and `/modules explain`
adds "left out for width in the last frame (higher-priority modules kept)" or
"shortened to fit the width in the last frame". A strip too narrow to show at all
reports every routed module as left out. A module turned off is still explained as
off. Nothing is collected or measured to produce it.

The Main Prompt and Right Context truncate text rather than drop modules; a
per-segment truncation trace there is left as future work (documented).

Refs #365
@raiseCatError
raiseCatError changed the base branch from fix/v021-flaky-tests to dev October 18, 2026 14:15
@raiseCatError
raiseCatError merged commit 7cb857f into dev Oct 18, 2026
12 checks passed
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