vt: ghostty_terminal_vt_write

This commit is contained in:
Mitchell Hashimoto
2026-03-13 19:35:41 -07:00
parent 302e68fd3d
commit 18fdc15357
4 changed files with 58 additions and 0 deletions

View File

@@ -79,6 +79,32 @@ GhosttyResult ghostty_terminal_new(const GhosttyAllocator* allocator,
*/
void ghostty_terminal_free(GhosttyTerminal terminal);
/**
* Write VT-encoded data to the terminal for processing.
*
* Feeds raw bytes through the terminal's VT stream parser, updating
* terminal state accordingly. Only read-only sequences are processed;
* sequences that require output (queries) are ignored.
*
* In the future, a callback-based API will be added to allow handling
* of output or side effect sequences.
*
* This never fails. Any erroneous input or errors in processing the
* input are logged internally but do not cause this function to fail
* because this input is assumed to be untrusted and from an external
* source; so the primary goal is to keep the terminal state consistent and
* not allow malformed input to corrupt or crash.
*
* @param terminal The terminal handle
* @param data Pointer to the data to write
* @param len Length of the data in bytes
*
* @ingroup terminal
*/
void ghostty_terminal_vt_write(GhosttyTerminal terminal,
const uint8_t* data,
size_t len);
/** @} */
#ifdef __cplusplus

View File

@@ -145,6 +145,7 @@ comptime {
@export(&c.sgr_attribute_value, .{ .name = "ghostty_sgr_attribute_value" });
@export(&c.terminal_new, .{ .name = "ghostty_terminal_new" });
@export(&c.terminal_free, .{ .name = "ghostty_terminal_free" });
@export(&c.terminal_vt_write, .{ .name = "ghostty_terminal_vt_write" });
// On Wasm we need to export our allocator convenience functions.
if (builtin.target.cpu.arch.isWasm()) {

View File

@@ -55,6 +55,7 @@ pub const paste_is_safe = paste.is_safe;
pub const terminal_new = terminal.new;
pub const terminal_free = terminal.free;
pub const terminal_vt_write = terminal.vt_write;
test {
_ = color;

View File

@@ -57,6 +57,16 @@ fn new_(
return ptr;
}
pub fn vt_write(
terminal_: Terminal,
ptr: [*]const u8,
len: usize,
) callconv(.c) void {
const t = terminal_ orelse return;
var stream = t.vtStream();
stream.nextSlice(ptr[0..len]);
}
pub fn free(terminal_: Terminal) callconv(.c) void {
const t = terminal_ orelse return;
@@ -110,3 +120,23 @@ test "new invalid value" {
test "free null" {
free(null);
}
test "vt_write" {
var t: Terminal = null;
try testing.expectEqual(Result.success, new(
&lib_alloc.test_allocator,
&t,
.{
.cols = 80,
.rows = 24,
.max_scrollback = 10_000,
},
));
defer free(t);
vt_write(t, "Hello", 5);
const str = try t.?.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("Hello", str);
}