首页
/ 在 Zed 中配置 Jsonnet 语言支持:安装扩展、语言服务器与 Tanka 导入解析实战指南

在 Zed 中配置 Jsonnet 语言支持:安装扩展、语言服务器与 Tanka 导入解析实战指南

2026-09-06 18:53:29作者:吴年前Myrtle

Jsonnet 是面向 Kubernetes、Grafana 等场景广泛使用的配置即代码语言,而 Zed 通过社区维护的 Jsonnet 扩展提供完整支持:由 Tree-sitter 语法树驱动高亮与结构导航,由 jsonnet-language-server 提供补全、诊断、格式化等语义能力。读完本篇,你将掌握在 Zed 中启用 Jsonnet 语言支持、通过 settings.jsonlsp 配置块向语言服务器透传工作区参数,以及为 Tanka 项目配置 resolve_paths_with_tanka 让 import 路径正确解析的完整方法。

Jsonnet 支持的整体架构

Jsonnet 并非 Zed 内置语言(在 语言支持总览 中未标注 *),其能力由社区维护的 Jsonnet 扩展提供。官方文档 Jsonnet 语言页 明确指出该扩展由两部分技术栈构成:

  • Tree-sitter:语法解析器来自 sourcegraph/tree-sitter-jsonnet,负责语法高亮、括号匹配、大纲(outline)等基于语法树的功能;
  • Language Server:语义后端使用 grafana/jsonnet-language-server,负责补全、错误诊断、跳转定义、格式化等功能。

这与 Zed 的通用语言支持模型完全一致——正如 配置语言支持 所概括的:Tree-sitter 处理"结构类"特性,LSP 处理"语义类"特性。理解这两层分工很重要,因为本文后面的配置只作用于语言服务器这一层。

从扩展系统内部看,一个语言扩展通常由语言元数据(config.toml)、语法注册(extension.toml 中的 [grammars.xxx])、Tree-sitter 查询(highlights.scm 等)以及语言服务器适配组成,详见 语言扩展开发文档。社区扩展 narqo/zed-jsonnet 正是按照这套机制将 Jsonnet 语言接入 Zed 的。

安装 Jsonnet 扩展

安装步骤如下:

  1. 打开 Zed 的扩展面板(快捷键由 zed::Extensions 动作触发,也可通过菜单栏进入),在扩展画廊中搜索 Jsonnet
  2. 找到社区扩展后点击安装;
  3. 安装完成后打开 .jsonnet / .libsonnet 文件,Zed 会自动启动 jsonnet-language-server

关于扩展的安装位置,扩展安装文档 给出了各平台默认目录:Linux 为 $XDG_DATA_HOME/zed/extensions~/.local/share/zed/extensions,macOS 为 ~/Library/Application Support/Zed/extensions,Windows 为 %LOCALAPPDATA%\Zed\extensions。其中 installed 子目录存放扩展源码,work 子目录存放扩展自身下载的语言服务器等运行时文件。

提示:如果团队希望统一预装扩展,可在设置中配置 auto_install_extensions(参见 全部设置参考 中的对应条目),使 Zed 在启动时自动安装指定扩展。

当 Jsonnet 扩展被加载后,Zed 会按 配置语言支持 中描述的流程自动下载或从 PATH 中寻找 jsonnet-language-server 可执行文件并启动它。

通过 lsp 配置块传递语言服务器参数

Jsonnet 扩展所依赖的 jsonnet-language-server 支持自定义配置。这些"工作区配置"通过 settings.json 中的 lsp 设置项传给语言服务器,适配器(adapter)名就是 jsonnet-language-server

下面是一个完整的配置示例,它让语言服务器借助 tanka(一个基于 Jsonnet 的 Kubernetes 配置工具)来解析 import 路径:

{
  "lsp": {
    "jsonnet-language-server": {
      "settings": {
        "resolve_paths_with_tanka": true
      }
    }
  }
}

配置要点解读:

  • lsp 是 Zed 设置中的顶层键,其下的子键对应各个语言服务器适配器的名称。由于 Zed 的自动补全会列出所有已识别的 LSP 适配器(而不仅是当前语言已启用的那些),你在敲 jsonnet-language-server 时即可获得候选提示;
  • settings 子键用于承载通过 LSP workspace/configuration 请求下发给服务器的配置。这种机制与 initialization_options 不同:后者只在服务器启动时通过 initialize 请求发送一次,修改后需要重启服务器才能生效;而 settings 允许服务器在运行期间多次主动查询,适合存放导入路径解析、格式化偏好这类"工作区级"配置。

关于两层配置机制的区别,配置语言支持 中也有专门说明,概括如下:

配置通道 下发方式 生效时机 典型用途
initialization_options initialize 请求携带一次 需重启语言服务器 rust-analyzer、clangd 等仅支持此类配置的服务器
settings workspace/configuration 请求按需查询 服务器运行期可多次获取 tailwindcss-language-server、jsonnet-language-server 等多数服务器
binary Zed 进程启动服务器时的命令行 重启生效 指定替代二进制、附加参数与环境变量

resolve_paths_with_tanka:让 Tanka 项目 import 解析正确的关键开关

settings 中唯一核心参数即 resolve_paths_with_tanka(布尔值)。默认情况下 jsonnet-language-server 按常规方式解析 Jsonnet 的 import/local 路径;而 Tanka 项目会在目录结构中引入与普通 Jsonnet 项目不同的 import 寻址约定(例如相对某个 jsonnetfile.json / vendor 目录展开引用)。当把该开关置为 true 时,语言服务器会改用 Tanka 的 import 解析策略来定位文件,从而使跨文件跳转、补全和诊断在 Tanka 工程内保持正确。

适用场景包括:

  • 直接维护 Tanka environments / 库结构、通过 tk 命令渲染 Kubernetes 清单的仓库;
  • 依赖 Jsonnet Bundler(jb)拉取 vendor 依赖、需要服务器识别 vendor 化 import 的项目;
  • 对纯 Jsonnet 项目而言,保持默认(不配置或置 false)即可。

从该选项的语义(resolve paths with tanka)可以推断,它并不修改 Jsonnet 语言本身的解析规则,而是替换路径解析这一环节的实现策略。若你的项目同时使用多种解析约定,可以结合 模型行(modelines) 等方式按文件微调,但一般情况下在项目级配置文件中统一打开该开关即可。

配置文件放在哪里

lsp 配置可以写在两类 settings.json 中:

  • 用户全局级:Linux 为 ~/.config/zed/settings.json,作用于本机所有项目;
  • 项目级:仓库根目录下的 .zed/settings.json,随项目提交、便于团队共享同一份语言服务器配置(正如 配置语言支持 中所举例的放置方式)。

建议对 Tanka 项目优先使用项目级配置,例如在仓库的 .zed/settings.json 中写入上面的 JSON 片段,所有协作者打开该仓库即自动生效。

从设置存储看 lsp 配置的分层合并

若想理解为什么用户级与项目级配置都能生效、以及同名键如何覆盖,可以查看 Zed 的设置存储实现 crates/settings/src/settings_store.rs。从该文件的结构可以看到,SettingsStore 内部同时维护了 default_settingsuser_settingsglobal_settingsextension_settingsserver_settings,以及以 (WorktreeId, RelPath) 为键、按工作树局部路径划分的 local_settings,最终通过多级合并(merged_settings)得到某个缓冲区实际生效的设置值。

这意味着 lsp 下的配置遵循 Zed 一贯的覆盖语义:项目级(local)设置优先于用户级(global)设置,用户级优先于默认值;同一服务器键名下若两侧都写了 settings,则按上述层级整块替换而非深合并。因此排查"配置没生效"问题时,应确认是否同时在多级配置里写了不同的 lsp.jsonnet-language-server 内容。

另外,Zed 要求在 lsp 中使用嵌套对象而不是点分隔字符串。例如若要表达嵌套键,必须写成嵌套 JSON 对象的形式——配置语言支持 中 TypeScript 一例专门强调了 VSCode 风格 "preferences.strictNullChecks" 这类点号写法在 Zed 中不被支持。所以对于 resolve_paths_with_tanka 也要放在 settings 对象内部、保持扁平的嵌套对象结构。

进一步定制:二进制路径、环境变量与开关控制

lsp 配置块还能控制语言服务器的启动方式,可参考 配置语言支持 中的 binary 用法:若希望使用系统已安装(而非 Zed 自动下载)的 jsonnet-language-server,或者想为其追加启动参数与环境变量,可扩展配置:

{
  "lsp": {
    "jsonnet-language-server": {
      "binary": {
        "path": "/path/to/jsonnet-language-server",
        "arguments": ["--log-level=info"],
        "env": {
          "JSONNET_PATH": "/path/to/vendor"
        }
      },
      "settings": {
        "resolve_paths_with_tanka": true
      }
    }
  }
}

其中 path 指向替代可执行文件,arguments 为追加的启动参数,env 注入额外环境变量。需要说明的是,binary 变更与 initialization_options 一样,在重启语言服务器后才生效(例如重新打开文件或重启 Zed)。

此外,若某个大仓库想整体关闭该语言的语义功能(仅保留 Tree-sitter 高亮),可在 languages 块中关闭语言服务器:

{
  "languages": {
    "Jsonnet": {
      "enable_language_server": false
    }
  }
}

同理,若 jsonnet-language-server 提供格式化能力且你想在保存时自动格式化,可把 Jsonnet 的 formatter 设为 "language_server" 并开启 format_on_save;格式化相关的通用写法同样参考 配置语言支持语言设置参考

小结

在 Zed 中使用 Jsonnet 的完整链路可以概括为三件事:

  1. 启用:通过扩展画廊安装社区 Jsonnet 扩展,让 Zed 获得 Tree-sitter 语法与 jsonnet-language-server 适配;
  2. 配置:在用户级 settings.json 或项目级 .zed/settings.jsonlsp.jsonnet-language-server.settings 中写入服务器参数;
  3. 适配场景:Tanka 工程打开 resolve_paths_with_tanka: true,普通 Jsonnet 项目维持默认即可。

如果你需要扩展其他语言的同类能力,可继续阅读 语言支持总览(含全部内置与社区语言索引)、配置语言支持lspinitialization_optionsbinaryenable_language_server 等机制的完整说明)以及 Jsonnet 语言页(本主题的官方原始文档)。

登录后查看全文
热门项目推荐
相关项目推荐