Skip to content

✨ hardware cursor positioning via text() caret - #103

Open
cowboyd wants to merge 20 commits into
mainfrom
cowboyd/text-caret
Open

✨ hardware cursor positioning via text() caret#103
cowboyd wants to merge 20 commits into
mainfrom
cowboyd/text-caret

Conversation

@cowboyd

@cowboyd cowboyd commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds a caret?: number property to the text() directive. When declared, the renderer positions the terminal's native cursor at the code-point offset within the text and manages cursor visibility automatically across frames.

Motivation: building a text input on top of the renderer requires the terminal cursor to track the insertion point and disappear when no input is focused. The cell where the caret sits depends on the text's layout and wrapping — information the renderer already has and the caller does not.

While painting a synthetic caret is always a possibility, the native caret is almost always going to be preferable.

2026-06-30 18 14 03

@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@bomb.sh/tty@103

commit: ee012e8

@cowboyd cowboyd changed the title ✨ feat(term): hardware cursor positioning via text() caret ✨ hardware cursor positioning via text() caret Jun 30, 2026
@cowboyd
cowboyd force-pushed the cowboyd/text-caret branch 2 times, most recently from cfc0338 to 4d7b8ca Compare July 1, 2026 08:05
@codspeed-hq

codspeed-hq Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 10 untouched benchmarks


Comparing cowboyd/text-caret (ee012e8) with main (917616b)

Open in CodSpeed

@cowboyd
cowboyd force-pushed the cowboyd/text-caret branch from 4d7b8ca to 9d23833 Compare July 2, 2026 15:29
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Size Increased — +0.5 KB

124.7 KB unpacked

cowboyd added 5 commits July 8, 2026 14:16
Adds a normative paragraph to §7.6 stating that a `caret` declaration on
empty content places the cursor at the text element's origin — the cell
where the first code point of `content` would be drawn if it were a
single space. Frames the empty-content case as a rendering commitment
the renderer must honor, without prescribing mechanism.
Substitute a single-space slice for empty text nodes carrying a caret
declaration so the layout engine emits one cell of geometry at the text
element's origin. Replaces the v1-limitation test with one asserting
the spec's outcome (CUP to row 1, col 1 + DECTCEM-show).
The `value || " "` fallback previously worked around the renderer's
inability to attach a caret to an empty text node. That case is now
handled directly by the renderer, so the example can pass the raw
value through and let the caret resolve at the input box's origin.
Precompute the caret's byte offset within its text node at OP_TEXT
decode time, then place the caret cell as a side effect of render_text's
existing walk: at the top of each iteration, if the current pointer
matches the target byte offset, record the cell.

Two edge cases fall out of the same mechanism. A slice whose first byte
is already past the target (Clay dropped whitespace at the wrap seam)
snaps the caret to the slice's origin — the start of the next wrapped
line — rather than orphaning it off the end of the previous line. And
the trailing cell of the last walked caret slice is remembered as the
end-of-content fallback for offset == content-length.

Deletes locate_caret, which walked slices with a code-point accumulator
that diverged from the caller's original offset whenever the layout
engine's wrap pass either dropped or retained-off-screen the seam
whitespace.

Adds tests covering both wrap-boundary cases and tightens the
previously-lax "correct wrapped line" assertion to an exact cell.
@cowboyd
cowboyd requested a review from natemoo-re July 29, 2026 19:42
@cowboyd
cowboyd requested a review from rauhryan July 29, 2026 19:42
@cowboyd
cowboyd marked this pull request as ready for review July 29, 2026 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants