Open
Conversation
Adds the v0.1 draft specification covering the architectural model, core invariants, public rendering API, descriptor model, and boundary responsibilities. Non-normative sections document settling surfaces (transfer encoding, input parsing, pointer events) separately from the stable rendering core.
Implement the virtualizer package for viewport virtualization over large terminal text output. This covers PRs 1–3 of the implementation plan: - PR 1: Export createDisplayWidth from renderer (WASM per-codepoint wcwidth, R.WIDTH.* tests) - PR 2: Virtualizer core — appendLine, resolveViewport, ring buffer, ANSI scanner, wrap walker, getLineDisplayWidth (~66 tests) - PR 3: scrollBy + scrollToFraction with all deferred scroll-dependent tests (~92 tests total) resize() still throws "not implemented" — deferred to PR 4.
Implement Virtualizer.resize(): clear wrap cache on column change, recompute estimated visual rows, clamp anchor sub-row. Row-only changes update rows without invalidation. Add 17 new tests: C.RESIZE.* (8), G.RESIZE.* (2), deferred C.APPEND.caches-displayWidth (1), exactness structural tests (6). 109 virtualizer tests total, 249 repo-wide.
Property tests cover identity monotonicity, eviction stability, estimation constraints, and viewport invariants under random ops. Benchmarks report informational gate results for all 7 perf gates.
16d6370 to
fbc05cd
Compare
commit: |
1. resize() now clamps anchorSubRow using exact wrap count instead of ceil(displayWidth/columns) estimate, which undercounts when boundary waste from wide characters increases actual sub-row count. 2. _recomputeCurrentEstimate() clamps currentEstimatedVisualRow to [0, totalEstimatedVisualRows-1] so the scrollbar invariant holds even when exact wrap counts exceed the estimate. 3. computeWrapPoints() no longer emits wrap point at index 0 when the first visible character is wider than columns — the character overflows its row instead of creating an empty first sub-row. Adds 4 regression tests covering all three fixes.
e31bd93 to
30b0eef
Compare
…dition
Fix two blocking issues before merge:
1. When maxLines=1 and isAtBottom=false, evicting the anchor line left
the anchor pointing at a gone lineIndex. resolveViewport() returned
no entries from a non-empty buffer. Removed the `lineCount > 1` guard
so the anchor always clamps to `evictedLineIndex + 1`. Added
regression test R.EVICT.maxLines1-not-at-bottom.
2. Resolved the contradiction between O-9 ("every slice fits within
columns") and the columns=1 + width-2 CJK glyph behavior. Documented
columns ≥ max glyph width as a precondition on VirtualizerOptions,
updated O-9 test name, wrap-golden test labels, and the spec.
Full-screen less-like pager that renders virtualizer viewport entries through Clay ops with line numbers, scrollbar, and status bar. Supports file args or generated content fallback.
Extract thumb geometry into reusable helper so event handling can hit-test the scrollbar. Left-click the thumb to drag, click the track to jump (top-aligned). Drag cancels on resize or mouseup.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Demo
Summary
createDisplayWidth()async WASM factory to@clayterm/clayterm— returns a synchronous per-codepointwcwidthstring-width function@clayterm/virtualizerpackage — viewport virtualization over large terminal text output with ring buffer storage, ANSI-aware line wrapping, scroll position tracking, and viewport resolutionVirtualizer API
Key design decisions:
measureWidthonly sees visible codepointsresolveViewport()computes exact wrap points for viewport entries whiletotalEstimatedVisualRowsusesceil(displayWidth/columns)for O(1) appendlineIndexvalues are never reused, even after FIFO eviction(anchorLineIndex, anchorSubRow)with bottom-follow behaviorTest coverage
125 test steps across 18 suites:
Test plan
deno testinvirtualizer/— 125 steps passdeno testin root — renderer width tests pass