Skip to content

Add line rendering mode, termcodes, and inline region demo#4

Merged
cowboyd merged 6 commits into
mainfrom
line-mode
Apr 10, 2026
Merged

Add line rendering mode, termcodes, and inline region demo#4
cowboyd merged 6 commits into
mainfrom
line-mode

Conversation

@cowboyd

@cowboyd cowboyd commented Apr 4, 2026

Copy link
Copy Markdown
Collaborator

Motivation

Clayterm currently renders using absolute CUP cursor positioning (\x1b[row;colH), which only works in full-screen alternate buffer mode. This makes it unsuitable for "inline TUI" use cases where a program renders a small region in the normal terminal scrollback — like how Claude Code renders each tool call output inline, or how a CLI shows a spinner then commits the result to scrollback.

Additionally, CUP sequences are meaningless when stdout is piped, so there's no way to produce pipe-friendly output.

Changes

Line rendering mode

Add a { mode: "line" } option to render() that emits newline-separated rows instead of CUP positioning sequences. This enables pipe-friendly output and front-buffer priming for efficient subsequent CUP diffs.

1-based row render option

Move the row offset from a constructor parameter to a render-time option ({ row }) that is 1-based, matching the ECMA-48 DSR/CPR native format. Callers can pass the queried cursor position directly without conversion. The row parameter is threaded through the C call chain (reducepresent_cupsemit_chemit_cursor) without struct mutation.

CursorEvent is now 1-based

CursorEvent.top/left renamed to CursorEvent.row/column, now 1-based to match DSR native format. The C parser no longer subtracts 1.

termcodes.ts module

Replaces csi.ts with a richer set of terminal escape code helpers:

  • ESC(), CSI() — low-level sequence builders
  • DSR() — Device Status Report request
  • SHOWCURSOR(), HIDECURSOR() — DECTCEM
  • ALTSCREEN(), MAINSCREEN() — xterm private mode 1049
  • saveCursorPosition() now uses DECSC/DECRC (ESC 7/ESC 8) instead of SCO (CSI s/CSI u)

All helpers are documented with JSDoc linking to the relevant specs (ECMA-48, VT510, xterm).

Inline region demo

New demo/inline-region.ts demonstrates the region lifecycle: allocate space with raw newlines, DSR to compute the row, then CUP-render all frames at the offset. Includes spinner, progress bar, and nyan cat examples. Uses termcodes throughout instead of raw escape sequences.

Other

  • Unified cells_clear/cells_invalidate into cells_fill(buf, w, h, ch, fg, bg)

Test plan

  • All 136 tests pass across 6 test suites
  • Line mode output contains no CUP sequences
  • Line mode primes front buffer for efficient subsequent diff renders
  • Row offset renders at correct 1-based terminal position
  • CursorEvent reports 1-based row/column matching DSR
  • deno fmt and deno lint clean

@pkg-pr-new

pkg-pr-new Bot commented Apr 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/clayterm@4

commit: e413755

@cowboyd cowboyd force-pushed the line-mode branch 4 times, most recently from 88e32f9 to 9f838c1 Compare April 9, 2026 16:55
@cowboyd cowboyd changed the title Add line rendering mode Add line rendering mode, termcodes, and inline region demo Apr 10, 2026
cowboyd added 6 commits April 10, 2026 16:06
Add { mode: "line" } option to render() that emits newline-separated
rows instead of CUP positioning sequences. Line mode writes every cell
and primes the front buffer, so subsequent diff renders work without
a full redraw.
This forces a render of all cells on the very first frame, which is
perfectly acceptable.
Move the row offset from a constructor parameter to a render-time
option. Row is now 1-based (matching ECMA-48 DSR/CPR format) so
callers can pass the queried cursor position directly without
conversion. Remove line mode from the inline region demo in favor
of raw newline allocation followed by CUP rendering for all frames.
Rename csi.ts to termcodes.ts and add ESC(), SHOWCURSOR(),
HIDECURSOR(), ALTSCREEN(), and MAINSCREEN() helpers. Make
CursorEvent.row/column 1-based to match DSR native format.
Replace all raw escape sequences in the demo with termcodes.
Use DECSC/DECRC (ESC 7/8) for cursor save/restore instead of
SCO (CSI s/u).
@cowboyd cowboyd merged commit 5372af8 into main Apr 10, 2026
5 checks passed
@cowboyd cowboyd deleted the line-mode branch April 10, 2026 21:42
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