Skip to content

Commit 4d7b8ca

Browse files
committed
linting & formatting
1 parent 692ab29 commit 4d7b8ca

4 files changed

Lines changed: 59 additions & 62 deletions

File tree

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ Do not include any agent marketing material (e.g. "Generated with...",
3131
- The renderer MUST NOT perform IO. It produces bytes; the caller writes them.
3232

3333
- The renderer MUST NOT manage terminal state (alternate buffer, mouse
34-
reporting, keyboard protocol modes). Cursor visibility and positioning
35-
are renderer-managed only when a `caret` declaration is present on
36-
a `text()` directive (see renderer-spec.md §7.6).
34+
reporting, keyboard protocol modes). Cursor visibility and positioning are
35+
renderer-managed only when a `caret` declaration is present on a `text()`
36+
directive (see renderer-spec.md §7.6).
3737

3838
- Each frame is a complete snapshot. The renderer carries no UI tree state
3939
between frames — only cell buffers for diffing.

specs/renderer-spec.md

Lines changed: 46 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -337,62 +337,56 @@ nests clip regions more deeply than the renderer can track:
337337
### 7.6 Hardware cursor visibility and positioning
338338

339339
A `text()` directive MAY declare a `caret` property whose value is a
340-
non-negative integer code-point offset into the directive's `content`.
341-
`0` means "before the first code point"; `[...content].length` means
342-
"after the last." Offsets in between sit immediately before the cell
343-
where the corresponding code point would render.
344-
345-
The cell where a declared caret sits is the cell at which the code
346-
point at the caret's offset would be drawn given the layout engine's
347-
text wrapping. For an offset `N`:
348-
349-
- If `N < [...content].length`, the caret's cell is the display
350-
position of the `N`-th code point (zero-indexed) within the rendered
351-
text.
352-
- If `N == [...content].length`, the caret's cell is one display
353-
position past the last rendered code point: on the same wrapped line
354-
if there is room, or at the start of the next line if the layout
355-
wraps at the end.
356-
- If `N > [...content].length` or `N < 0`, behavior is unspecified;
357-
callers must keep offsets within bounds.
358-
359-
Display position accounts for code points wider than one cell (CJK,
360-
fullwidth forms, some emoji): such code points occupy two cells, and
361-
the caret sits at the first cell of the pair. Cell widths are
362-
determined by the same measurement the renderer uses to lay out the
363-
text itself.
364-
365-
The renderer manages the terminal's hardware cursor based on the
366-
presence of `caret:` declarations:
367-
368-
- When the current frame contains one or more `caret:` declarations,
369-
the rendered `output` MUST, when written to the terminal, leave the
370-
hardware cursor visible at the cell where the first declared caret
371-
(in directive order) sits.
340+
non-negative integer code-point offset into the directive's `content`. `0` means
341+
"before the first code point"; `[...content].length` means "after the last."
342+
Offsets in between sit immediately before the cell where the corresponding code
343+
point would render.
344+
345+
The cell where a declared caret sits is the cell at which the code point at the
346+
caret's offset would be drawn given the layout engine's text wrapping. For an
347+
offset `N`:
348+
349+
- If `N < [...content].length`, the caret's cell is the display position of the
350+
`N`-th code point (zero-indexed) within the rendered text.
351+
- If `N == [...content].length`, the caret's cell is one display position past
352+
the last rendered code point: on the same wrapped line if there is room, or at
353+
the start of the next line if the layout wraps at the end.
354+
- If `N > [...content].length` or `N < 0`, behavior is unspecified; callers must
355+
keep offsets within bounds.
356+
357+
Display position accounts for code points wider than one cell (CJK, fullwidth
358+
forms, some emoji): such code points occupy two cells, and the caret sits at the
359+
first cell of the pair. Cell widths are determined by the same measurement the
360+
renderer uses to lay out the text itself.
361+
362+
The renderer manages the terminal's hardware cursor based on the presence of
363+
`caret:` declarations:
364+
365+
- When the current frame contains one or more `caret:` declarations, the
366+
rendered `output` MUST, when written to the terminal, leave the hardware
367+
cursor visible at the cell where the first declared caret (in directive order)
368+
sits.
372369

373370
- When the current frame contains no `caret:` declarations:
374-
- If the previous frame contained one, the rendered `output` MUST
375-
leave the hardware cursor hidden.
376-
- Otherwise, the rendered `output` MUST NOT include
377-
cursor-positioning or cursor-visibility bytes; the caller's
378-
cursor state is preserved.
371+
- If the previous frame contained one, the rendered `output` MUST leave the
372+
hardware cursor hidden.
373+
- Otherwise, the rendered `output` MUST NOT include cursor-positioning or
374+
cursor-visibility bytes; the caller's cursor state is preserved.
379375

380376
The byte-level path the renderer takes to satisfy these outcomes is
381-
implementation-defined. The renderer MAY hide the cursor before cell
382-
writes to prevent flicker, MAY omit such a hide for in-place edits
383-
where flicker is acceptable, MAY emit only a CUP when the caret has
384-
moved within an already-visible state, MAY use whatever escape-sequence
385-
path it judges appropriate. Only the post-frame cursor state above is
386-
normative.
387-
388-
If more than one `caret:` declaration is present in a frame, the
389-
renderer SHOULD use the first in directive order for the hardware
390-
cursor. Behavior for additional declarations is intentionally
391-
unspecified, leaving room for a future multi-cursor extension without
392-
breaking this contract.
393-
394-
This responsibility is limited to the hardware cursor's position and
395-
visibility. Cursor shape and blink rate remain caller-managed.
377+
implementation-defined. The renderer MAY hide the cursor before cell writes to
378+
prevent flicker, MAY omit such a hide for in-place edits where flicker is
379+
acceptable, MAY emit only a CUP when the caret has moved within an
380+
already-visible state, MAY use whatever escape-sequence path it judges
381+
appropriate. Only the post-frame cursor state above is normative.
382+
383+
If more than one `caret:` declaration is present in a frame, the renderer SHOULD
384+
use the first in directive order for the hardware cursor. Behavior for
385+
additional declarations is intentionally unspecified, leaving room for a future
386+
multi-cursor extension without breaking this contract.
387+
388+
This responsibility is limited to the hardware cursor's position and visibility.
389+
Cursor shape and blink rate remain caller-managed.
396390

397391
---
398392

src/clayterm.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,14 @@ struct Clayterm {
8888
* first text node carrying a caret declaration per frame, then locates
8989
* the corresponding cell after Clay layout. had_caret_last_frame is the
9090
* only cross-frame bit retained. */
91-
const char *caret_text_chars; /* start of caret-bearing text node's bytes, or NULL */
92-
int caret_text_length; /* byte length of that text node */
93-
uint32_t caret_offset; /* code-point offset within that text node */
94-
int caret_x, caret_y; /* resolved cell (column, row), valid only when caret_text_chars != NULL */
95-
int has_caret; /* 1 when the current frame placed a caret */
96-
int had_caret_last_frame; /* 1 when the previous frame placed a caret */
91+
const char
92+
*caret_text_chars; /* start of caret-bearing text node's bytes, or NULL */
93+
int caret_text_length; /* byte length of that text node */
94+
uint32_t caret_offset; /* code-point offset within that text node */
95+
int caret_x, caret_y; /* resolved cell (column, row), valid only when
96+
caret_text_chars != NULL */
97+
int has_caret; /* 1 when the current frame placed a caret */
98+
int had_caret_last_frame; /* 1 when the previous frame placed a caret */
9799
};
98100

99101
/* Memory layout inside the arena provided by the host:

test/term.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// deno-lint-ignore-file no-control-regex
12
import { beforeEach, describe, expect, it } from "./suite.ts";
23
import { createTerm, type Term } from "../term.ts";
34
import {
@@ -130,7 +131,7 @@ describe("term", () => {
130131
let out = decode(
131132
term.render(box("hello world"), { mode: "line" }).output,
132133
);
133-
// deno-lint-ignore no-control-regex
134+
134135
expect(out).not.toMatch(/\x1b\[\d+;\d+H/);
135136
expect(out.split("\n").length).toBe(5);
136137
expect(trim(print(out, 20, 5))).toEqual(`

0 commit comments

Comments
 (0)