Ghostty 示例工程实战:example 目录如何驱动 libghostty-vt 的 C/Zig 两种 API
本文以仓库 example/README.md 为主线,系统讲解 Ghostty 官方的 example/ 示例工程集合:每个示例都是独立的库 API 演示项目,按 c-/zig- 前缀区分所用语言,统一通过 zig build / zig build run 构建运行。读完后你将掌握:如何在任何示例目录下用一条命令编译运行、示例工程 build.zig 中 lazy dependency 与静态/动态链接的取舍、CMake/Swift/WASM 等变体构建方式,以及如何从最小示例源码读懂 libghostty-vt 的实际调用链。
example 目录是什么:独立可构建的库 API 演示工程
example/README.md 对示例目录的定位非常明确:
Standalone projects demonstrating the Ghostty library APIs. The directories starting with
c-use the C API and the directories starting withzig-use the Zig API.
即 example/ 下每个目录都是一个独立工程(standalone project),专门演示 Ghostty 库 API 的用法;目录名前缀 c- 表示使用 C API,zig- 表示使用 Zig API。结合 example/AGENTS.md 的约定,可以确认每个示例的标准目录结构为:
build.zig—— Zig 构建脚本(所有示例共用一套模板);build.zig.zon—— Zig 包清单,声明对 Ghostty 的依赖;README.md—— 该示例的说明文档;src/main.c或src/main.zig—— 示例主程序。
以最小的 C 示例 example/c-vt 为例,其完整文件集就是上述四件套(README.md、build.zig、build.zig.zon、src/main.c)。
从仓库实际内容看,当前示例已扩展到约 30 个,除文档明确列举的 c-/zig- 两大类外,还包括面向其他构建体系的变体:
| 类别 | 代表目录 | 说明 |
|---|---|---|
| C API 基础演示 | c-vt、c-vt-stream、c-vt-sgr、c-vt-colors、c-vt-formatter | OSC/SGR 解析、VT 流处理、颜色、格式化等 |
| C API 进阶演示 | c-vt-render、c-vt-search、c-vt-selection、c-vt-paste、c-vt-kitty-graphics、c-vt-effects | 渲染状态、搜索、选区、粘贴、Kitty 图形协议、终端效果回调 |
| C API 编码类演示 | c-vt-encode-key、c-vt-encode-mouse、c-vt-encode-focus、c-vt-size-report、c-vt-color-scheme | 按键/鼠标/焦点事件、尺寸与配色报告编码为转义序列 |
| 构建方式变体 | c-vt-static、c-vt-cmake、c-vt-cmake-static、c-vt-cmake-cross | 静态链接、CMake FetchContent、跨平台交叉编译 |
| Zig API 演示 | zig-vt、zig-vt-stream、zig-formatter | 直接使用 ghostty-vt Zig 模块 |
| 其他语言/平台 | cpp-vt-stream、swift-vt-xcframework、wasm-vt、wasm-sgr、wasm-key-encode | C++ 兼容性验证、Swift XCFramework、WebAssembly |
每个示例自身的 README 还反复强调一点:示例虽然用 Zig 构建系统来构建,但 Ghostty 对外发布的是标准 C 库,可以用任意 C 工具链消费,Zig 构建只是为了复用仓库的构建逻辑并直接依赖源码树。
构建与运行:zig build run 的统一入口
example/README.md 给出的运行方式是全部 30 余个示例(Zig 构建的那部分)的统一入口:
cd example/<dir>
zig build run
其中 <dir> 替换为目标示例目录名。原文特别指出:即便是 C API 示例,使用的也是 Zig 构建系统(而非 Zig 语言)来构建项目。这句话的底层依据可以直接在 example/c-vt/build.zig 中看到:
const exe_mod = b.createModule(.{
.target = target,
.optimize = optimize,
});
exe_mod.addCSourceFiles(.{
.root = b.path("src"),
.files = &.{"main.c"},
});
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.
if (b.lazyDependency("ghostty", .{
// Setting simd to false will force a pure static build that
// doesn't even require libc, but it has a significant performance
// penalty. If your embedding app requires libc anyway, you should
// always keep simd enabled.
// .simd = false,
})) |dep| {
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
}
这段构建脚本传达了三个关键信息:
addCSourceFiles说明构建的是 C 源码(src/main.c),Zig 在这里只是充当跨平台 C 编译器与链接器的角色;b.lazyDependency("ghostty", ...)表示 Ghostty 库以 lazy 方式引入——只有真正需要构建时才拉取/编译依赖,随后linkLibrary(dep.artifact("ghostty-vt"))链接ghostty-vt构件。example/AGENTS.md 将“所有 C 示例均通过lazyDependency("ghostty", ...)链接ghostty-vt”列为硬约定;.simd = false选项的取舍:开启后会产生纯静态、甚至不依赖 libc 的构建,但源码注释明确说明这会带来显著性能惩罚;如果你的宿主应用本来就需要 libc,应始终保持 simd 启用。
依赖声明在 example/c-vt/build.zig.zon 中:
.ghostty = .{ .path = "../../" },
// Example of what a URL-based dependency looks like:
// .ghostty = .{
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
// },
示例仓库内用 .path = "../../" 指向源码树自身,保证始终测试与当前检出配套的代码;而注释中给出的 URL 形式(配合 .hash 校验和)才是外部项目消费 Ghostty 库的标准姿势。清单中还有两个与 example/AGENTS.md 约定对应的字段:.minimum_zig_version(当前为 0.15.1,各示例保持一致)和 .fingerprint(新增示例时必须生成新的唯一 u64 随机值)。
最小 C 示例源码走读:OSC 解析器
c-vt 是整个示例集合中最能体现“库 API 长什么样”的工程,其 src/main.c 用约 40 行演示了 OSC(Operating System Command)解析的完整生命周期:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>
int main() {
GhosttyOscParser parser;
if (ghostty_osc_new(NULL, &parser) != GHOSTTY_SUCCESS) {
return 1;
}
// Setup change window title command to change the title to "hello"
ghostty_osc_next(parser, '0');
ghostty_osc_next(parser, ';');
const char *title = "hello";
for (size_t i = 0; i < strlen(title); i++) {
ghostty_osc_next(parser, title[i]);
}
// End parsing and get command
GhosttyOscCommand command = ghostty_osc_end(parser, 0);
// Get and print command type
GhosttyOscCommandType type = ghostty_osc_command_type(command);
printf("Command type: %d\n", type);
// Extract and print the title
if (ghostty_osc_command_data(command, GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR, &title)) {
printf("Extracted title: %s\n", title);
} else {
printf("Failed to extract title\n");
}
ghostty_osc_free(parser);
return 0;
}
调用链可以概括为四步:
ghostty_osc_new(NULL, &parser)创建解析器,返回值与GHOSTTY_SUCCESS比较判断成败;- 逐字符喂入
ghostty_osc_next(parser, byte)——这里模拟的是OSC 0 ; hello(改变窗口标题)序列; ghostty_osc_end(parser, 0)结束解析并得到GhosttyOscCommand,再通过ghostty_osc_command_type取命令类型、ghostty_osc_command_data按数据种类(此处为GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR)提取字符串载荷;ghostty_osc_free(parser)释放资源。
所有符号的声明都在公共头文件 include/ghostty/vt.h 及其包含的 include/ghostty/vt/ 目录下。example/AGENTS.md 还说明了一个文档与示例之间的隐性关联:include/ghostty/vt/ 中的头文件通过 Doxygen @snippet 标签引用示例源码(用 //! [snippet-name] 标记包裹),因此示例代码本身就是官方 API 文档的一部分——这也是为什么修改示例代码时必须保持 snippet 标记与头文件同步。
对应的 Zig 版本 example/zig-vt/src/main.zig 则展示了同一库的 Zig 模块形态:
const std = @import("std");
const ghostty_vt = @import("ghostty-vt");
pub fn main(init: std.process.Init) !void {
// Initialize a terminal.
var t: ghostty_vt.Terminal = try .init(init.io, init.gpa, .{
.cols = 6,
.rows = 40,
});
defer t.deinit(init.gpa);
// Write some text. It'll wrap because this is too long for our
// columns size above (6).
try t.printString("Hello, World!");
// Get the plain string view of the terminal screen.
const str = try t.plainString(init.gpa);
defer init.gpa.free(str);
std.debug.print("{s}\n", .{str});
}
对比 C 版本可以看出 Zig 模块直接导出类型化 API(ghostty_vt.Terminal),创建 6 列终端、写入文本、再取纯文本视图三步完成,无需逐字节驱动解析器。
其他构建方式:CMake、静态链接、交叉编译、XCFramework 与 WASM
zig build run 是默认路径,但 example/ 中另有一组示例专门演示脱离 Zig 构建系统的消费方式,它们的 README 中给出了完整的可复制命令:
CMake + FetchContent
c-vt-cmake 演示从 CMake 工程消费 libghostty-vt(FetchContent 拉取,创建终端、写入 VT 序列、格式化屏幕为纯文本):
cd example/c-vt-cmake
cmake -B build
cmake --build build
./build/c_vt_cmake
c-vt-cmake-static 是同一模式的静态库版本。两者都支持通过 -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../.. 改为直接构建本地检出,而不从远端抓取:
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../..
cmake --build build
交叉编译
c-vt-cmake-cross 演示使用 CMake 函数 ghostty_vt_add_target() 以静态链接方式交叉编译 libghostty-vt,目标平台按主机自动选择(可用 -DZIG_TARGET=... 覆盖):
| Host | Target |
|---|---|
| Linux | Windows (MinGW) |
| Windows | Linux (glibc) |
| macOS | Linux (glibc) |
cd example/c-vt-cmake-cross
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../..
cmake --build build
file build/c_vt_cmake_cross
Zig 内静态链接
c-vt-static 的 README 说明它与 c-vt 的唯一区别是链接 ghostty-vt-static 构件而非普通 ghostty-vt 构件,用于展示静态链接形态。
Swift XCFramework
swift-vt-xcframework 演示通过预构建 XCFramework 让 Swift Package 消费 libghostty-vt,构建顺序是先在仓库根目录生成 XCFramework,再进入示例目录构建:
zig build -Demit-lib-vt
cd example/swift-vt-xcframework
swift build
swift run
WebAssembly
wasm-vt、wasm-sgr、wasm-key-encode 三个浏览器示例共享同一条前置构建命令(在仓库根目录执行):
zig build -Demit-lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall
产物为 zig-out/bin/ghostty-vt.wasm。README 特别强调:必须通过 HTTP 访问(如 python3 -m http.server 8000 从仓库根目录启动),浏览器禁止从 file:// URL 加载 WASM 文件。三个示例分别对应:初始化终端并写入 VT 数据后格式化为纯文本、解析 SGR 样式序列、按键事件编码。
值得注意的边界:C++ 与 WASM 示例不是 zig build run 成员
cpp-vt-stream 是 c-vt-stream 的 C++ 移植,其 README 明确指出 libghostty 是 C 库,该示例的存在目的是让 CI 验证库可在 C++ 模式下编译;而三个 wasm-* 示例的入口是浏览器页面(各自目录下的 index.html),不是可执行工程。选择示例时注意这一区别。
从源码结构看:示例背后的公共能力面
浏览 example/ 中各示例 README 的一句话定位,可以归纳出 libghostty-vt 对外暴露的能力面,这也是 include/ghostty/vt/ 头文件组织的镜像:
- 终端状态机:c-vt-stream 与 zig-vt-stream 用
ghostty_terminal_vt_write/vtStream演示“只读终端”模式——解析 VT 序列、更新终端状态,但对需要应答的查询(如设备状态查询)不予响应,适用于回放工具、CI 日志查看器、PaaS 构建输出等场景; - 屏幕读取与呈现:c-vt-formatter(格式化纯文本)、c-vt-grid-traverse(逐格遍历 codepoint/行状态/样式)、c-vt-grid-ref-tracked(长生命周期跟踪单元格引用)、c-vt-render(渲染状态迭代、脏区跟踪);
- 交互事件:c-vt-selection / c-vt-selection-gesture(选区与合成手势)、c-vt-paste(普通/bracketed/unsafe-paste 确认/Kitty 剪贴板协议)、c-vt-search(查找栏式匹配导航);
- 协议编码:按键(Kitty 协议,示例产出
\x1b[57442;5:3u)、鼠标(SGR 格式,示例产出形如\x1b[<0;6;3M的序列)、焦点、尺寸报告、配色报告,分别对应 c-vt-encode-key、c-vt-encode-mouse、c-vt-encode-focus、c-vt-size-report、c-vt-color-scheme; - 系统接口与高级特性:c-vt-effects(
write_pty/bell/title_changed/clipboard_write回调,剪贴板收到的是解码后的二进制安全 MIME 表示)、c-vt-kitty-graphics(通过ghostty_sys_set安装 PNG 解码回调后接收 Kitty 图形协议图像)、c-vt-compression(回滚区压缩:库本身不创建定时器或后台线程,嵌入方负责在空闲后调度增量压缩并串行化访问)、c-vt-snapshot(快照编码与一次性/增量两种解码路径)、c-vt-modes(模式标识打包/解包与 DECRPM 应答编码)、c-vt-colors(默认颜色、OSC 覆盖的叠加行为)。
新增一个示例:仓库维护者的标准流程
如果你要为 libghostty-vt 增加新的 API 演示,example/AGENTS.md 给出了维护者视角的完整流程,可帮助读者理解示例工程之间的同构性来源:
- 复制一个现有示例目录(如
c-vt-encode-focus/)作为起点; - 修改
build.zig.zon:改.name,生成新的唯一.fingerprint(随机u64十六进制字面量),保持.minimum_zig_version与其他示例一致; - 修改
build.zig中可执行文件的.name与目录名一致; - 按既有格式撰写
README.md。
三条硬约定同样值得记住:可执行文件名使用下划线(c_vt_encode_focus 而非连字符);所有 C 示例通过 lazyDependency("ghostty", ...) 链接 ghostty-vt;build.zig 遵循统一模板。此外 CI 通过 example/*/build.zig.zon 通配自动发现新示例,无需修改任何 workflow 文件——这解释了为什么每个目录必须自带 build.zig.zon。
小结
example/README.md 篇幅不长,但它定义了 Ghostty 库 API 学习路径的基本规则:目录前缀决定 API 语言,cd example/<dir> && zig build run 是统一入口,Zig 构建系统只是手段、标准 C 库才是目标产物。配合 example/AGENTS.md 的工程约定和 example/c-vt、example/zig-vt 等最小示例源码,你可以快速判断某个能力(OSC 解析、VT 流处理、选区、快照……)对应的示例与头文件位置;而 CMake/静态/交叉编译/XCFramework/WASM 五组变体示例则覆盖了真实嵌入场景中几乎所有主流构建路径。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00