Commit Graph

29 Commits

Author SHA1 Message Date
Mitchell Hashimoto
3cf01e8445 libghostty: add utf-8 grapheme cell getter to C API
Add a render-state row-cells getter that encodes the current cell's
full grapheme cluster directly as UTF-8 into a caller-provided
GhosttyBuffer. The getter writes the base codepoint first, followed by
any extra grapheme codepoints, and follows the existing buffer-writer
convention where len is bytes written on success or required capacity
on GHOSTTY_OUT_OF_SPACE.

Previously C consumers could query grapheme codepoints, but bindings
that needed UTF-8 text had to reconstruct and encode the cluster
themselves. That duplicated terminal internals in downstream bindings
and made users pay for awkward cross-language struct handling. By
owning the UTF-8/grapheme behavior in libghostty, bindings can use one
stable C API and optionally wrap it with small binding-local helpers.
2026-05-28 12:33:36 -07:00
Mitchell Hashimoto
8beea5f92d libghostty: expose row cell styling bit
Add a render row-cells data key for querying whether the current cell has
explicit styling. This lets consumers avoid fetching a raw cell or full style
snapshot when all they need is the cell's HasStyling bit.

The new key is appended to the existing enum for ABI safety and is served by
the existing row-cells getter path. Existing data keys and function exports are
unchanged.
2026-05-27 21:10:26 -07:00
Mitchell Hashimoto
edf2da0157 libghostty: expose per-cell selection state
Render-state rows already expose their selected range, but
cell-oriented C API consumers had to fetch that row range separately
and duplicate the containment check while rendering.

Add a SELECTED row-cells data kind that carries the row selection into
the row-cells wrapper and returns whether the current cell column is in
that inclusive range. The field remains separate from cell colors and
style so selection stays an explicit render overlay policy.

For performance reasons, the span-based row getter is recommended still
but this is a convenient thing to do for cell-oriented folks.
2026-05-24 20:24:16 -07:00
Mitchell Hashimoto
24048ffd47 libghostty: expose row-local render selections
Render state already tracks the selected cell range for each viewport row,
but C renderers could only get the full terminal selection. That required
consumers to map global selection pins back into row-local spans themselves.

Add row selection data to the render-state row API. Querying the new row
data returns GHOSTTY_NO_VALUE for unselected rows and writes the inclusive
start and end columns for selected rows. The render example now demonstrates
setting a selection and reading the row-local range while iterating rows.
2026-05-23 15:03:51 -07:00
Mitchell Hashimoto
2c1dad790b libghostty: add _get_multi to all _get APIs
Replace the ImageInfo and PlacementInfo sized structs and their
associated .info enum variants with a new _get_multi pattern that
batches multiple enum+pointer pairs into a single call. This avoids
struct ABI concerns (field order, padding, alignment, GHOSTTY_INIT_SIZED)
while preserving the single-call-crossing performance benefit for FFI
and Cgo callers.

Each _get_multi function takes an array of enum keys, an array of
output pointers, and an optional out_written parameter that reports
how many values were successfully written before any error. This
applies uniformly to all _get APIs: terminal_get, cell_get, row_get,
render_state_get, render_state_row_get, render_state_row_cells_get,
kitty_graphics_image_get, and kitty_graphics_placement_get.

The C example is updated to use compound-literal _get_multi calls,
and tests cover both success and error paths for every new function.
2026-04-11 12:51:36 -07:00
Mitchell Hashimoto
945920a186 vt: expose terminal default colors via C API
Add set/get support for foreground, background, cursor, and palette
default colors through ghostty_terminal_set and ghostty_terminal_get.

Four new set options (COLOR_FOREGROUND, COLOR_BACKGROUND, COLOR_CURSOR,
COLOR_PALETTE) write directly to the terminal color defaults. Passing
NULL clears the value for RGB colors or resets the palette to the
built-in default. All set operations mark the palette dirty flag for
the renderer.

Eight new get data types retrieve either the effective color (override
or default, via DynamicRGB.get) or the default color only (ignoring
any OSC overrides). Effective getters for RGB colors return the new
NO_VALUE result code when no color is configured. The palette getters
return the current or original palette respectively.

Adds the GHOSTTY_NO_VALUE result code for cases where a queried value
is simply not configured, distinct from GHOSTTY_INVALID_VALUE which
indicates a caller error.
2026-03-26 09:51:30 -07:00
Mitchell Hashimoto
3c9c3a4f54 terminal/c: use lib.alloc instead of direct lib/allocator.zig import
Each C API file independently imported ../../lib/allocator.zig as
lib_alloc. Now that terminal/lib.zig re-exports the allocator module
as lib.alloc, use that instead. This removes the redundant import
and keeps all lib dependencies flowing through the single lib.zig
entry point.
2026-03-25 07:31:21 -07:00
Mitchell Hashimoto
2f2f003aa5 terminal/c: use lib.calling_conv to allow Zig calling conv 2026-03-25 07:28:22 -07:00
Mitchell Hashimoto
f50aa90ced terminal: add lib.zig to centralize lib target and re-exports
Previously every file in the terminal package independently imported
build_options and ../lib/main.zig, then computed the same
lib_target constant. This was repetitive and meant each file needed
both imports just to get the target.

Introduce src/terminal/lib.zig which computes the target once and
re-exports the commonly used lib types (Enum, TaggedUnion, Struct,
String, checkGhosttyHEnum, structSizedFieldFits). All terminal
package files now import lib.zig and use lib.target instead of the
local lib_target constant, removing the per-file boilerplate.
2026-03-25 07:25:16 -07:00
Mitchell Hashimoto
3c8d0a9c25 vt: fix test failures in render and key_encode
The colors_get function used structSizedFieldFits to guard the
palette copy, which required the entire palette array to fit in the
provided size. This prevented partial palette writes when the caller
passed a truncated sized struct, since the guard failed even though
the inner code already handled partial copies correctly. Remove the
outer guard so the existing partial-copy logic applies.

The setopt_from_terminal test expected alt_esc_prefix to be false on
a fresh terminal, but the mode definition in modes.zig sets its
default to true. Update the test expectation to match.
2026-03-23 09:23:32 -07:00
Mitchell Hashimoto
58283528c7 vt: handle invalid enum before pointer cast in getters
The inline else switch in each C API getter expands the .invalid
case, which has OutType void. When called with .invalid and a null
out pointer, the @ptrCast(@alignCast(out)) panics before getTyped
can return early.

Handle .invalid explicitly in the outer switch of every getter to
short-circuit before the pointer cast. This affects build_info,
cell, row, terminal, osc, and render (three getters).
2026-03-23 09:19:52 -07:00
Mitchell Hashimoto
8bd3a493be libghostty: add resolved bg_color and fg_color to cells API
Fixes #11705

Add bg_color and fg_color options to GhosttyRenderStateRowCellsData
that resolve the final RGB color for a cell, flattening the multiple
possible sources. For background, this handles content-tag bg_color_rgb,
content-tag bg_color_palette (looked up in the palette), and the
style bg_color. For foreground, this resolves palette indices through
the palette; bold color handling is not applied and is left to the
caller.

Both return GHOSTTY_INVALID_VALUE when no explicit color is set, in
which case the caller should fall back to whatever default color it
wants (e.g. the terminal background/foreground).
2026-03-21 20:30:01 -07:00
Mitchell Hashimoto
918840cf1d vt: persist VT stream state across vt_write calls
Previously, every call to vt_write created a fresh ReadonlyStream with
new Parser and UTF8Decoder state. This meant escape sequences split
across write boundaries (e.g. ESC in one write, [27m in the next)
would lose parser state, causing the second write to start in ground
state and print the CSI parameters as literal text.

The C API now stores a persistent ReadonlyStream in the TerminalWrapper
struct, which is created when the Terminal is initialized. The vt_write
function feeds bytes through this stored stream, allowing it to maintain
parser state across calls. This change ensures that escape sequences
split across write boundaries are correctly parsed and rendered.
2026-03-21 11:18:02 -07:00
Mitchell Hashimoto
e7a18ea5b3 vt: fix render state cell style and graphemes_buf APIs
The GRAPHEMES_BUF data kind previously required a double pointer
(pointer to a uint32_t*) because the OutType was [*]u32, making the
typed out parameter *[*]u32. Change OutType to u32 so that callers
pass a plain uint32_t* buffer directly, which is the natural C
calling convention. The implementation casts the out pointer to
[*]u32 internally to write into the buffer.

The STYLE data kind read directly from the render state style array
without checking whether the cell actually had non-default styling.
The style data is undefined for unstyled cells, so this caused a
panic on a corrupt enum value when the caller read the style of an
unstyled cell. Now check cell.hasStyling() first and return the
default style for unstyled cells.

Expand the c-vt-render example to exercise dirty tracking, color
retrieval, cursor state, row/cell iteration with style resolution,
and dirty state reset. Break the example into six doxygen snippet
regions and reference them from render.h.
2026-03-20 09:24:31 -07:00
Mitchell Hashimoto
d9df4154db vt: add cursor field data getters to render state API
Expose the cursor fields from RenderState.Cursor through the C API
via new GhosttyRenderStateData enum values. This adds getters for
visual style, visibility, blink state, password input detection,
and viewport position (x, y, wide tail).

A new GhosttyRenderStateCursorVisualStyle enum maps the Zig
cursor.Style values (bar, block, underline, block_hollow) to
stable C integer constants. Viewport position getters return
GHOSTTY_INVALID_VALUE when the cursor is not visible within
the viewport.
2026-03-20 09:05:20 -07:00
Mitchell Hashimoto
60ea2d76d4 vt: add color data getters to render state
Add individual color data kinds to GhosttyRenderStateData so callers
can query background, foreground, cursor color, cursor-color presence,
and the full 256-color palette through ghostty_render_state_get()
without using the sized-struct colors API.

COLOR_CURSOR returns GHOSTTY_INVALID_VALUE when no explicit cursor
color is set; callers can check COLOR_CURSOR_HAS_VALUE first.
2026-03-20 08:57:23 -07:00
Mitchell Hashimoto
6ae17a02af vt: add cell-level iteration and data access to render state row cells
Add next, select, and get functions to the render state row cells
API, mirroring the row iterator pattern. row_cells_next advances to
the next cell sequentially, row_cells_select jumps to a specific
column index with bounds validation, and row_cells_get queries data
for the current cell position.

The get function supports querying raw cell values (GhosttyCell),
resolved styles (GhosttyStyle), grapheme codepoint counts, and
writing grapheme codepoints into a caller-provided buffer.

Also add Cell.C and Cell.cval() to page.zig, matching the existing
Row.C/Row.cval() pattern, so the render state can convert cells to
the C ABI type without a raw bitCast.
2026-03-20 08:53:45 -07:00
Mitchell Hashimoto
ecd1d0d1e1 vt: decouple row iterator allocation from population
Change row_iterator_new to only allocate with undefined fields,
matching the pattern used by row_cells_new. The iterator is now
populated via the render state get API with a new .row_iterator
data kind, which slices the row data and resets y to null.

This separates the lifetime of the opaque handle from the render
state it iterates, letting callers allocate once and re-populate
from different states without reallocating.
2026-03-20 08:20:27 -07:00
Mitchell Hashimoto
75b49051a3 vt: add GhosttyRenderStateRowCells opaque type
Add a new opaque RowCells type that wraps per-row cell data
(raw cells, graphemes, styles) for the C API. The caller
allocates a RowCells handle via row_cells_new, then populates
it by passing it to row_get with the new .cells data kind.
This queries the current row from the iterator and slices the
underlying MultiArrayList into the RowCellsWrapper fields.

The new type and functions are wired through main.zig,
lib_vt.zig, and the render.h C header.
2026-03-20 07:25:52 -07:00
Mitchell Hashimoto
33e81ffb75 vt: use get/set pattern for row iterator data access
Replace ghostty_render_state_row_dirty_get and
ghostty_render_state_row_dirty_set with generic
ghostty_render_state_row_get and ghostty_render_state_row_set
functions using enum-dispatched data/option kinds.
2026-03-20 07:17:00 -07:00
Mitchell Hashimoto
459583a6c3 vt: use get/set pattern for render state data access
Replace the individual ghostty_render_state_size_get,
ghostty_render_state_dirty_get, and ghostty_render_state_dirty_set
functions with generic ghostty_render_state_get and
ghostty_render_state_set functions that use enum-dispatched data
kinds and option kinds, following the same InType/OutType pattern
used by the terminal and mouse encoder C APIs.
2026-03-20 07:00:14 -07:00
Mitchell Hashimoto
900afa7b80 fix types 2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
2147b9d65c vt: row dirty tracking 2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
f610d7e00f vt: add render_row_iterator_next 2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
ad0e47ebac vt: cover c row iterator new/free
Add a C ABI row-iterator handle for render state with
ghostty_render_state_row_iterator_new and
ghostty_render_state_row_iterator_free, and wire them through
src/terminal/c/main.zig, src/lib_vt.zig, and
include/ghostty/vt/render.h. The header now documents only the
currently exported iterator API.
2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
b35f8ed16e vt: expose render state colors in C API
Add a C-facing GhosttyRenderStateColors sized struct and a
ghostty_render_state_colors_get accessor so renderers can read
background, foreground, cursor color state, and palette data directly
from the render state.
2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
b830a0ee1d vt: add size getter for render state
Add ghostty_render_state_size_get() to return cols and rows from the
current render state using out pointers. The C wrapper validates null
inputs, the symbol is wired through the C API export layers, and tests
cover success and invalid-value paths.
2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
2876fb7a55 vt: expose dirty state in C API
Switch RenderState.Dirty to lib.Enum so it uses C-compatible enum
backing when building the C ABI target. Add GhosttyRenderStateDirty and
new ghostty_render_state_dirty_get/set declarations to the render header,
then wire both functions through src/terminal/c/main.zig and the lib_vt
export table.
2026-03-19 20:13:14 -07:00
Mitchell Hashimoto
a0d738697e vt: add c render state api and example
Introduce the first public C render-state surface for libghostty-vt.
Before this change, the render-state path was only available in Zig,
so C embedders had no direct way to create and update that cache.

Add an opaque GhosttyRenderState type with new, update, and free
entry points, then wire those symbols through the C API bridge and
library exports. Keep the surface intentionally minimal for now so
ownership and update behavior are established before adding read
accessors.
2026-03-19 20:13:14 -07:00