
Zed Rust 扩展 API 实战指南extension.toml、WASM 构建到 Extension trait 实现全解【免费下载链接】zedCode at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.项目地址: https://gitcode.com/GitHub_Trending/ze/zed本文围绕 Zed 仓库中的 crates/extension_api/README.md 展开讲解如何用 Rust 编写 Zed 扩展的完整流程extension.toml清单文件怎么写、Cargo 如何打包为 WebAssemblyWASM组件、Extensiontrait 有哪些可重写的钩子、开发期如何在 Zed 内加载本地扩展以及zed_extension_api与 Zed 各版本之间的兼容矩阵。结合 crates/extension_api/src/extension_api.rs 的源码实现与 extensions/glsl/ 这个官方内置参考扩展读完后你可以独立搭建一个可下载语言服务器、可读取 Zed 设置、可运行于 Zed 扩展宿主中的 Rust 扩展。1. 扩展运行机制为什么扩展是一个 WASM 组件README 的第一句话点明了这个 crate 的定位This crate lets you write extensions for Zed in Rust.并说明“Zed extensions are packaged as WebAssembly files”。这句话的底层实现在 crates/extension_api/src/extension_api.rs 中可以找到对应crate 的[lib]入口就是src/extension_api.rs见 crates/extension_api/Cargo.toml它依赖wit-bindgen 0.41并在内部通过wit_bindgen::generate!宏绑定./wit/since_v0.8.0目录下的 WIT 接口定义最后用wit::export!(Component)把实现导出为 WebAssembly Component Model 组件WIT 接口按“自某版本起可用”组织crates/extension_api/wit/ 下从since_v0.0.1一路排到since_v0.8.0每一版新增的能力如lsp.wit、process.wit、context-server.wit、dap.wit都是分阶段加入的这就是后文兼容矩阵的结构化来源当前工作区中该 crate 的版本号是0.8.0且publish falseCargo.toml 中注释写明“Change back to true when were ready to publish v0.8.0”。也就是说仓库里这份代码对应的是尚未发布的 0.8.0写扩展时应以已发布的最高版本README 兼容表中为0.6.0为准选择依赖版本。这套机制决定了写扩展的两条硬约束扩展只能使用 Zed 通过 WIT 接口暴露的能力下载文件、HTTP 请求、读文件、执行命令、读设置等不能直接依赖宿主机文件系统之外的系统 API扩展以 WASI 目标编译因此构建时需要wasm32-wasip2rustup 目标。2. 扩展清单extension.toml 的结构与字段README 要求在扩展目录根部放置extension.toml结构如下id my-extension name My Extension description ... version 0.0.1 schema_version 1 authors [Your Name youexample.com] repository https://github.com/your/extension-repository对照仓库内置扩展 extensions/glsl/extension.toml 可以看到真实字段的用法id glsl name GLSL description GLSL support. version 0.2.4 schema_version 1 authors [Mikayla Maki mikaylazed.dev] repository https://github.com/zed-industries/zed [language_servers.glsl_analyzer] name GLSL Analyzer LSP language GLSL [grammars.glsl] repository https://github.com/theHamsta/tree-sitter-glsl commit 31064ce53385150f894a6c72d61b94076adf640a各部分的作用可以这样理解字段/表说明id/name/version扩展的唯一标识、显示名与语义化版本Zed 用id定位扩展目录schema_version清单格式版本当前为1authors/repository作者与源码仓库用于扩展市场的展示[language_servers.key]声明该扩展提供的语言服务器language字段把 LSP 关联到具体语言[grammars.key]声明扩展携带的 Tree-sitter 语法从指定仓库的固定 commit拉取languages/目录GLSL 扩展在 extensions/glsl/languages/glsl/ 下附带了config.toml、highlights.scm、brackets.scm、indents.scm、injections.scm这些文件由 Zed 在加载扩展时读取用于配置高亮、括号匹配、缩进与语法注入规则3. Cargo 元数据把 crate 编译成 cdylibREADME 给出的 Cargo.toml 关键片段是[dependencies] zed_extension_api 0.6.0 [lib] crate-type [cdylib]crate-type [cdylib]是必须的因为 WASM 组件的产物就是动态库形式的.wasm。仓库内置扩展 extensions/glsl/Cargo.toml 是一个更完整的对照样本[package] name zed_glsl version 0.2.4 edition.workspace true publish.workspace true license Apache-2.0 [lib] path src/glsl.rs crate-type [cdylib] [dependencies] zed_extension_api 0.1.0两个值得注意的点zed_glsl依赖的是zed_extension_api 0.1.0而 API 仓库当前版本已到0.8.0。这正体现了 README 兼容表的含义扩展用哪个 API 版本编译就锁定在对应的 Zed 版本能力集合内老扩展不需要跟进升级[lib] path src/glsl.rs说明单文件扩展完全可行不需要复杂的模块结构。4. 实现扩展Extension trait 与 register_extension! 宏README 给出的最小骨架是use zed_extension_api as zed; struct MyExtension { // ... state } impl zed::Extension for MyExtension { // ... } zed::register_extension!(MyExtension);要理解这段代码在做什么需要看 crates/extension_api/src/extension_api.rs 中的三处实现**1ExtensiontraitL69-L284**定义了扩展的全部可重写钩子全部带默认实现按需覆盖即可。按功能域分组语言服务器LSPlanguage_server_command返回启动命令默认返回错误、language_server_initialization_options/language_server_workspace_configuration返回 JSON 字符串形式的初始化选项与工作区配置、language_server_initialization_options_schema/language_server_workspace_configuration_schema返回 JSON Schema供 Zed 校验用户设置、language_server_additional_initialization_options/language_server_additional_workspace_configuration向另一个语言服务器透传选项UI 标签label_for_completion/label_for_symbol返回CodeLabel即“可被 Tree-sitter 解析的代码片段 高亮 span”用于在补全列表和符号面板里渲染带语法高亮的代码标签斜杠命令complete_slash_command_argument与run_slash_command后者返回SlashCommandOutput支持分节的输出上下文服务器context_server_command/context_server_configuration对应 0.5.0 起引入的context-server.wit文档索引suggest_docs_packages/index_docs为/docs斜杠命令提供包名建议与索引写入通过KeyValueStore调试适配器DAPget_dap_binary、dap_request_kind判断 launch 还是 attach、dap_config_to_scenario、dap_locator_create_scenario/run_dap_locator两阶段解析先把 Zed Task 转成调试场景必要时带 build task再在构建完成后解析出最终调试请求——对应 0.6.0 引入的dap.wit。**2register_extension!宏L289-L334**是扩展的“入口装配器”。展开后它会生成一个导出符号为init-extension的 C 函数__init_extension调用你的类型 as Extension::new()构造实例并写入全局静态变量EXTENSIONL348。WIT 中对应的声明是export init-extension: func()见 crates/extension_api/wit/since_v0.8.0/extension.wit。宏还包含一段 WASI 专属逻辑拦截chdir并返回NOTSUPerrno 58禁止扩展修改进程当前工作目录并把 CWD 固定为环境变量PWD——这解释了扩展在 WASI 沙箱中为什么只能相对固定的工作目录操作文件。**3impl wit::Guest for ComponentL366-L562**是宿主调用扩展的桥梁宿主通过 WASM 组件模型调用的每个函数如language_server_command、run_slash_command都被转发到extension()拿到的用户扩展实例上JSON 类型的配置值在这层用serde_json序列化/反序列化。此外crate 在wasm32目标下会额外导出一个ZED_API_VERSION字节数组L350-L353链接到zed:api-version段Zed 宿主据此校验扩展编译时使用的 API 版本——这就是兼容表能生效的机制。GLSL 扩展extensions/glsl/src/glsl.rs展示了 trait 的典型用法覆盖new初始化cached_binary_path: None、language_server_command与language_server_workspace_configuration结尾一句zed::register_extension!(GlslExtension);完成注册全文 130 行即一个完整可用的 LSP 扩展。5. 扩展可用的宿主能力WIT import 一览extension.wit的world extension块crates/extension_api/wit/since_v0.8.0/extension.wit列出了扩展可以调用的宿主能力context-server、dap、github、http-client、platform、process、nodejs等 import 组。其中对扩展作者最常用的几组工作区与项目访问worktreeresource 提供id、root_path、read_text_file、which在$PATH中查找二进制、shell_env当前 shell 环境变量projectresource 提供worktree_ids。文件与状态download-file按DownloadedFileType——gzip/gzip-tar/zip/uncompressed——下载并解压到扩展工作目录、make-file-executableWindows 上是 no-op、set-language-server-installation-status上报downloading/checking-for-update/failed状态给 UI。HTTP 客户端crates/extension_api/src/http_client.rs 提供HttpRequest::builder()链式 API——method(...)、url(...)、header(...)、body(...)、redirect_policy(...)默认NoFollow然后build()得到请求.fetch()执行.fetch_stream()获取流式响应。这意味着扩展不直接联网而是由 Zed 宿主代为发请求。进程执行crates/extension_api/src/process.rs 的Command::new(program).arg(...).env(...).output()运行子进程并返回Output。GitHub APIlatest_github_release/github_release_by_tag_name用于获取 release 及其资产配合download_file是下载语言服务器二进制的标准套路。设置读取crates/extension_api/src/settings.rs 提供LanguageSettings::for_worktree、LspSettings::for_worktree、ContextServerSettings::for_project等类型化包装底层统一走 WIT 的get_settings(path, category, key)导入并按 worktree 定位。GLSL 扩展正是用它读取lsp.glsl_analyzer设置并原样转发给语言服务器extensions/glsl/src/glsl.rs。一个完整的“查找 → 下载 → 安装语言服务器”流程在 GLSL 扩展中可见extensions/glsl/src/glsl.rs先worktree.which(glsl_analyzer)找系统二进制再查本地缓存否则上报CheckingForUpdate调用latest_github_release按current_platform()选出aarch64/x86/x86_64 × macos/linux-musl/windows资产download_file解压后make_file_executable最后清理旧版本目录并缓存路径。6. 开发期测试Install Dev Extension 流程README 给出的本地调试步骤安装 Rust安装 WASI 目标rustup target add wasm32-wasip2在命令面板中执行zed: extensions打开扩展视图点击右上角Install Dev Extension按钮选择你的扩展目录路径。Zed 会读取该目录下的extension.toml与预编译的 WASM 产物直接加载。仓库自带的扩展开发工具链可参考 script/bump-extension-cli 与 crates/extension_cli/扩展 CLI 工具负责编译、打包等工程化操作。7. 版本兼容矩阵README 原文强调“Extensions created using newer versions of the Zed extension API wont be compatible with older versions of Zed.” 兼容矩阵如下Zed 版本zed_extension_api版本0.192.x0.0.1-0.6.00.186.x0.0.1-0.5.00.184.x0.0.1-0.4.00.178.x0.0.1-0.3.00.162.x0.0.1-0.2.00.149.x0.0.1-0.1.00.131.x0.0.1-0.0.60.130.x0.0.1-0.0.50.129.x0.0.1-0.0.40.128.x0.0.1注意两点适用前提该表以 README 为准描述的是已发布 API 版本仓库中0.8.0尚未发布publish false其新增能力如wit/since_v0.8.0相较since_v0.6.0的扩展需待发布后才有对应的 Zed 版本支持单向兼容的含义是老 Zed 无法加载用新 API 编译的扩展新导出接口宿主不认识而新 Zed 可以运行老 API 编译的扩展since_v0.0.1等目录保留即为此服务。因此给广泛用户发布的扩展应尽量选择兼容窗口内的 API 版本编译。8. 小结从清单到注册的心智模型把一个 Rust 扩展放进 Zed 的完整链路是extension.toml声明身份与资源语言服务器、语法→ Cargo 以cdylib编译出 WASM 组件依赖zed_extension_api对应版本→wit_bindgen按since_v*接口生成宿主调用桩 →register_extension!宏导出init-extension入口并冻结扩展实例 → 运行时宿主按需调用language_server_command、run_slash_command、get_dap_binary等钩子扩展则反过来通过download_file、fetch、Command、get_settings等 WIT import 使用宿主能力。仓库中的 extensions/glsl/、extensions/html/、extensions/proto/ 都是可直接阅读的参考实现API 的后续变更方向可跟踪 crates/extension_api/PENDING_CHANGES.md。【免费下载链接】zedCode at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.项目地址: https://gitcode.com/GitHub_Trending/ze/zed创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考