Skip to content

fix: preserve inline views after multi-screen Println - #1826

Open
rsbin1178 wants to merge 1 commit into
charmbracelet:mainfrom
rsbin1178:fix/inline-multiscreen-println
Open

rsbin1178 wants to merge 1 commit into
charmbracelet:mainfrom
rsbin1178:fix/inline-multiscreen-println

Conversation

@rsbin1178

Copy link
Copy Markdown
  • I have read CONTRIBUTING.md.
  • I have created a discussion that was approved by a maintainer (for new features).

The Discussion item is not applicable: this is a bug fix for #1822, not a new feature.

Summary

Fixes #1822.

A single multi-screen Println can remove an already-painted, unchanged inline View. The printed rows remain complete and ordered, but the managed View disappears and its cursor is left at the end of the printed block.

This change:

  • Uses the execution-time width and managed-frame height to bound row reservations by the actual free space.
  • Handles an empty or full-height managed frame by releasing only that region, allowing ordinary terminal scrolling, and repainting it without clearing native history.
  • Keeps pending flush, insertion, and View/cursor restoration in one renderer-lock transaction.
  • Restores the View and cursor immediately, even when View equality would otherwise skip the flush.

No public API changes are introduced. Program-level propagation of insertion errors is intentionally outside this focused fix; tea.go is unchanged. Renderer-level write and short-write checks are retained.

Relationship to existing work

Related: #1741 and #1766.

Those proposals concern pending-View synchronization and printing before the initial flush. The regression here explicitly flushes an unchanged View before printing, uses fixed geometry, and inserts 80 short ASCII rows in one call. It does not rely on resize, model switching, streaming, or raw terminal clearing.

The synchronization changes overlap those proposals because frame geometry and final restoration must remain consistent throughout insertion. This PR acknowledges that overlap and can be coordinated with those changes; it does not claim those reports are unrelated.

Regression coverage

TestCursedRenderer_insertAboveMultiScreen verifies that the initial View is actually visible, then checks the terminal screen, cursor, shell history, and all ordered/unique output rows immediately after insertion, before another render or cleanup.

The test fails on unmodified production sources at ff51ba4c51f85875761b15a64f9ab9aa0eaa9fa1 and passes with this patch. Additional cases cover pending/shrunken/empty/full-height/oversized frames, subsequent Views and insertions, hidden cursors, ANSI/wide/exact-margin text, alternate screen, and writer failures.

A test-only x/vt dependency supplies terminal-state assertions rather than relying only on escape-stream substrings. Upstream's Go 1.26.0 minimum and production dependency versions are unchanged. The examples checksum updates keep its module tidy.

Validation

Executed locally on macOS arm64:

  • Root tests with Go 1.27.1 and the supported minimum Go 1.26.0.
  • go test -race -count 4 -cpu 1,4 ./....
  • Focused insertion tests repeated ten times with race detection.
  • go vet ./..., root/examples builds and tests, and tidy/idempotence checks.
  • Configured golangci-lint v2.9.0 with Go 1.26.0: 0 issues; formatting and diff checks clean.
  • Govulncheck: no vulnerabilities found.
  • A separate verification pass repeated root tests/race/vet/build/lint without requiring source changes.

An independent public-API repro was also run in a 40x10 controlling PTY on macOS 26.5.1 arm64 with Go 1.26.6 and pyte 0.8.2. Four captures each with and without NO_COLOR confirmed that the base loses its controls/cursor while the candidate preserves them, all 80 rows, and shell history. Snapshots are taken after print completion and before repair input or Quit. Terminal modes are restored after Program.Run returns.

Windows/amd64 and Linux/amd64 test binaries were cross-compiled, not executed. Remote GitHub CI and broader GUI-terminal coverage are not claimed by these local results.

@rsbin1178
rsbin1178 force-pushed the fix/inline-multiscreen-println branch from 6715092 to 38f887e Compare October 3, 2026 03:37
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.

[v2] Multi-screen Println removes an already-rendered inline View

1 participant