Update the pinned Ghostty main commit and expose the new decoder option and data query for retaining restored VT continuation state.\n\nDecoded terminals previously always disabled continuation tracking. Callers can now opt into preserving the exact unfinished parser state with the decoder's configured continuation limit. Tests cover the default, retained state, and option lifecycle.
Add benchmark coverage for snapshot reader decoding and VT Writer formatting across empty, plain, Unicode, styled, and large terminal states.
Previously each formatter call allocated a cgo writer handle and crossed into Go for every native fragment. Retain one handle per formatter and coalesce fragments in a binding-side buffer so steady-state writes are allocation-free and use bounded callbacks.
Lazily install terminal effect userdata and co-allocate callback reader state with its snapshot decoder. This removes registry and wrapper allocations from decode paths while preserving on-demand effects for restored terminals.
Update the pinned Ghostty revision to current upstream main. This
revision adds the ghostty_formatter_format writer API.
Use the new API for Formatter.WriteTo so output streams through the
shared writer bridge. Preserve partial byte counts and original
callback errors.
The Go formatter options previously omitted the native terminal formatter selection field, so callers could not restrict formatter output while emitting terminal extras.
Add WithFormatterSelection and materialize the selection in temporary C-owned memory for the constructor. The native formatter copies the selection during creation; document the lifetime of its borrowed grid references. Add coverage for selection, terminal extras, and constructor copy semantics.
Formatter.WriteTo previously returned a nil error when a writer accepted only part of the formatted output, allowing silent truncation. Return io.ErrShortWrite when the accepted count differs and the writer reports no error, while preserving the accepted count and any original writer error.\n\nAdd regression coverage for a writer that accepts one byte without reporting the required error.
Advance the pinned libghostty-vt revision to upstream main. The new headers replace the dedicated render color getter and add structured cursor and color reads, dirty-row traversal, packed cell views, semantic prompt state, and new OSC variants.
Bind the native additions, expose manifest-driven packed cell access, refresh the WASM-only API inventory, and add coverage for the new render fast paths and terminal state.
Advance the pinned libghostty-vt revision to upstream main. The new revision requires Zig 0.16.0 and adds APIs for detecting and writing through VT stream ground boundaries.
Expose the ground-state query and bounded write operation through typed Go methods. Cover already-ground, partial-consumption, unfinished-sequence, and empty-input behavior in tests.
Advance the FetchContent pin from da59a2ec to d929e6a3 so builds use the latest upstream main revision.
The exported VT headers are unchanged across this range, so the Go bindings require no accompanying API updates.
Advance the pinned Ghostty revision to upstream main. The previous
bindings referenced removed mode getter and setter functions and did not
expose the new terminal configuration and effect APIs.
Use the generic terminal data and option paths for modes, add default
mode configuration, title reporting, terminfo names, and unknown-sequence
callbacks, and align snapshot documentation with the revised format.
Add Go benchmarks covering empty, ASCII, Unicode, styled, and 10K-line history states across allocating and reused-buffer encoding plus full and READY-prefix decoding.
Return C out parameters through small value structs to avoid cgo-forced heap escapes. Pin immutable byte input for zero-copy decoding, and retain an explicit copying constructor for callers that need mutation isolation.
Update the pinned Ghostty revision to main and expose the new snapshot,
stream continuation, reader, and writer APIs through idiomatic Go wrappers.
The bindings previously had no way to persist and incrementally restore
complete terminal state.
Preserve callback errors across cgo, support incremental history restoration,
and adapt Kitty graphics metadata to pending payloads. Add coverage for
buffer, callback, lifecycle, and validation paths.
Update the pinned Ghostty revision to the latest main commit. The new
revision introduces desktop notification and progress report effects.
Expose both effects through creation options and live setters. Copy
borrowed notification strings into Go memory, translate progress states,
and validate sized callback structs before access.
Cover OSC 9, OSC 777, and OSC 9;4 callback behavior, clearing,
split writes, and all progress states.
Update the pinned Ghostty revision and Zig overlay for the upstream
Zig 0.16 requirement. Adapt terminal construction and configuration
to the new scrollback limit ABI and temporary-file policy.
Bind the remaining native OSC, SGR, color, Unicode, formatter,
render, reporting, compression, and metadata APIs. Add typed accessors
and tests, leaving only WebAssembly-only allocation helpers unbound.
ghostty-org/ghostty#13182
Update the pinned libghostty revision to include the clipboard write
API and expose its protocol-neutral descriptors through Go callbacks.
Clipboard effects copy borrowed C descriptors into Go-owned MIME
representations, support constructor and live registration, and return
the upstream result enum. Cover OSC 52 and iTerm2 writes, clears,
ignored reads, binary payloads, and callback removal.
Update the pinned ghostty source to pick up the new render-cell
GRAPHEMES_UTF8 data getter and GhosttyBuffer type.
AppendGraphemes no longer carries a binding-local implementation of
grapheme UTF-8 encoding. It now calls the upstream getter through a
small C-stack wrapper, which keeps the GhosttyBuffer out-parameter off
the Go heap while letting libghostty own the grapheme extraction and
encoding behavior.
This preserves the allocation-avoiding Go API while reducing the
binding-side code to a thin adapter over the upstream API.
AppendGraphemes previously queried grapheme length into a Go local
and used a Go stack scratch buffer for the common short-grapheme case.
Both values were passed through cgo, which forced them to escape to the
heap on every non-empty cell.
Move the hot path into a small C helper that keeps the length and
codepoint scratch storage on the C side, encodes the grapheme cluster
as UTF-8, and returns the result metadata by value. The Go wrapper now
only passes the caller byte buffer through cgo and grows that buffer
when the helper reports GHOSTTY_OUT_OF_SPACE.
This preserves the existing AppendGraphemes API while avoiding the
extra per-cell heap allocation that made the direct UTF-8 path slower
than caller-reused GraphemesInto scratch.
RenderCellStyle used pointer fields for foreground and background colors
that pointed back into storage owned by the same struct. Reusing a single
style value in a per-cell render loop still forced the destination to
escape, producing heap allocations for heavily styled output.
Store resolved colors as values with explicit presence booleans instead
and make StyleInto fill that shape directly. The binding helper now
returns its snapshot by value rather than writing through a Go pointer, so
cgo does not force a temporary snapshot allocation on every call.
Add RenderCellStyle plus StyleInto and ResolvedStyleInto for row-cell
rendering. The new API lets callers reuse one destination value while
reading resolved foreground, background, has-styling, and common text
style flags.
Previously renderers had to call Style, FgColor, BgColor, and
HasStyling separately. That allocated Go wrapper values and crossed cgo
multiple times per styled cell. The new binding-side helper batches the
existing libghostty queries into one cgo transition and treats absent
foreground or background colors as nil fields instead of errors.
RenderStateRowCells.Graphemes previously allocated a fresh codepoint
slice for every text cell. That made plaintext renderers pay allocation
and conversion costs even when most cells contained a single ASCII
codepoint.
Add GraphemesInto so callers can reuse their own codepoint scratch
buffer, and add AppendGraphemes for renderers that want UTF-8 bytes
directly. The existing Graphemes API now delegates through the reusable
path while preserving its nil result for empty cells.
Bind the libghostty selection APIs for deriving word, line,
select-all, and command-output selections from terminal grid refs. The
new Go entry points use option structs so future C option fields can be
added without changing method signatures.
Add one-shot selection formatting helpers and selection inspection
operations for adjustment, ordering, containment, and equality. Render
state rows can now expose their row-local selected cell range, matching
the upstream row selection data API.
Expose the remaining partially-bound C constants listed in TODO.md.
Build info now includes version pre-release metadata, modes expose
DECBKM, and terminal bindings expose active selection data plus APC
buffer and selection setters. The terminal selection accessor maps
GHOSTTY_NO_VALUE to a nil selection to match existing optional getter
patterns.
Remove the completed constants from TODO.md.
Add human-friendly text serialization to the input enum types via
the standard encoding.TextMarshaler and encoding.TextUnmarshaler
interfaces. This makes them work transparently with encoding/json,
TOML, YAML, XML, and flag.TextVar.
Each type gains:
- String() string returning the canonical snake_case name
(e.g. "key_a", "arrow_down", "shift+ctrl", "middle",
"gained").
- MarshalText() ([]byte, error) returning the same bytes as
String. Mods(0) marshals to an empty byte slice.
- UnmarshalText([]byte) error mutating the receiver.
- A top-level ParseKey, ParseMods, ParseMouseButton, and
ParseFocusEvent function as an ergonomic alternative to the
pointer-receiver UnmarshalText.
The Key and MouseButton names follow the upstream Zig source
naming. Mods is rendered as a stable "+"-joined list of
individual flag names; UnmarshalText accepts either "+" or ","
as separators and supports the upstream aliases (cmd/command for
super, opt/option for alt, control for ctrl).
add String/FromString for Key, Mods, MouseButton, FocusEvent
Add human-friendly string conversion to the input enum types so they
can be serialized to and parsed from text formats like JSON or
configuration files.
Each type gains a String() method returning the canonical
snake_case name (e.g. "key_a", "arrow_down", "shift+ctrl",
"middle", "gained") and a pointer-receiver FromString method
that mutates the receiver. A top-level NewKeyFromString,
NewModsFromString, NewMouseButtonFromString, and
NewFocusEventFromString constructor is also provided as a more
ergonomic alternative.
Extensive notes on concurrency
Document and test cross-compilation
One of the common stigmas of cgo in Go projects is that it makes
cross-compilation overly difficult. Its more difficult than pure Go projects,
to be sure, but with the right shape of libraries and build scripts, it
can be made to work well. libghostty is a good example of this.
libghostty only depends on libc and the Zig compiler (tool, not language)
as a drop-in replacement for c/c++ compilation means we can easily
cross-compile!
This commit adds documentation, tests, and examples on how to do this.
terminal: fix checkptr failure under -race for cgo.Handle userdata