libtermy
Embeddable Termy terminal engine with Rust and C ABI surfaces.
libtermy is very experimental. It is not as performant as the native Termy app, can have bugs, and is subject to breaking changes between releases. Do not rely on it for production workloads yet.
libtermy is the embeddable Termy terminal engine. The first cut is split
into:
termy_core— Rust API for a single headless terminal surface.termy_ffi— C ABI wrapper overtermy_core.
The core API owns PTY startup, terminal parsing, input writes, resize, event draining, damage snapshots, and renderer-neutral frame snapshots. It does not depend on GPUI and does not expose Termy's app chrome, tabs, panes, or tmux session model as part of the public v1 surface.
termy_core can also load Termy's normal config format through the existing
headless termy_config_core parser. Config loading returns the full parsed
AppConfig, parse diagnostics, and a TerminalRuntimeConfig ready to pass
into terminal creation. Missing default config files fall back to defaults
without creating files; explicit missing paths are reported as load errors.
Rust Embedding
Use termy_core::Terminal directly:
let loaded_config = termy_core::load_config_from_default_path()?;
let cell_metrics = termy_core::measure_cell_from_config(&loaded_config.app_config);
let terminal = termy_core::Terminal::new(
termy_core::TerminalSize {
cols: 80,
rows: 24,
cell_width: cell_metrics.cell_width,
cell_height: cell_metrics.cell_height,
},
None,
None,
None,
Some(&loaded_config.runtime_config),
None,
)?;
terminal.write(b"echo hello\r");
let frame = terminal.snapshot();TermyFrame contains a flat row-major Vec<TermyCell>, cursor state, scroll
state, and cell colors as simple RGBA bytes.
Use termy_core::measure_cell(font_family, font_size, line_height) or
termy_core::measure_cell_from_config(&app_config) to derive the
TerminalSize cell width and height from Termy's font metrics instead of
guessing a monospace ratio in the host app.
C ABI
Use termy_ffi as an opaque-handle API:
crates/ffi/include/termy.htermy_config_load_defaulttermy_config_load_pathtermy_config_from_contentstermy_config_freetermy_terminal_new_with_configtermy_terminal_newtermy_terminal_freetermy_terminal_writetermy_terminal_resizetermy_terminal_snapshottermy_frame_freetermy_terminal_take_damagetermy_damage_freetermy_terminal_drain_eventstermy_event_batch_freetermy_terminal_searchtermy_search_batch_free
Any returned frame, damage, event batch, search batch, or standalone byte
payload must be released by the matching termy_*_free function. Event
payloads owned by an event batch are freed by termy_event_batch_free; do
not free them separately. Search match line payloads owned by a search batch
are freed by termy_search_batch_free.
Embedders should synchronize access to a terminal handle if they call into it from multiple threads.
Config Diagnostics
Config diagnostics are available through termy_config_diagnostics and must
be released with termy_config_diagnostics_free.
| Kind | Meaning |
|---|---|
1 | unknown section |
2 | unknown root key |
3 | unknown color key |
4 | invalid syntax |
5 | invalid value |
6 | duplicate root key |
Render Config
Renderer-facing config values are available through
termy_config_render_config and must be released with
termy_render_config_free. This returns the parsed font family, font size,
line height, padding, background opacity, cursor blink, cursor style, and
measured cell width/height so non-Rust embedders can render the terminal with
the same user config that was passed into termy_terminal_new_with_config.
Event Kinds
| Kind | Meaning |
|---|---|
1 | wakeup |
2 | title |
3 | reset title |
4 | bell |
5 | exit |
6 | clipboard store |
7 | shell prompt start |
8 | shell command start |
9 | shell command executing |
10 | shell command finished |
11 | progress |
12 | working directory |
Progress States
| Value | Meaning |
|---|---|
0 | clear |
1 | in progress |
2 | error |
3 | indeterminate |
4 | warning |
Cursor Styles
| Value | Meaning |
|---|---|
1 | line |
2 | block |
Search
Search returns visible-frame matches only. Each TermyFfiSearchMatch reports
the row, inclusive start and end columns, and the visible line text that
matched.
The C ABI header is at crates/ffi/include/termy.h.