ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Zed 语言配置实战:Tree-sitter 高亮、LSP 语言服务器与格式化器完整指南

Zed 语言配置实战:Tree-sitter 高亮、LSP 语言服务器与格式化器完整指南 Zed 语言配置实战Tree-sitter 高亮、LSP 语言服务器与格式化器完整指南【免费下载链接】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/zedZed 的语言支持建立在 Tree-sitter语法高亮与结构分析与 LSP语义智能两大技术支柱之上。本文基于 Zed 官方文档 configuring-languages.md系统讲解语言级设置、文件关联、语言服务器选择与配置、格式化与 Lint、语法高亮主题覆盖以及语言服务器特性的使用方法并结合仓库源码说明各配置项的解析与合并规则帮助你为不同编程语言定制一套可复制、可落地的 Zed 配置。一、Zed 语言支持的两大支柱Zed 的语言支持由两项技术协作完成Tree-sitter负责语法高亮以及基于结构的功能例如大纲面板outline panelLanguage Server ProtocolLSP语言服务器提供语义能力包括代码补全、诊断diagnostics、跳转定义与代码重构。本文覆盖的内容包括语言级设置、文件关联、语言服务器配置、格式化、Lint 以及语法高亮。支持的完整语言列表见 Supported Languages为 Zed 添加新语言支持的方式见 Language Extensions。二、语言级设置languagesZed 允许针对单个语言覆盖全局设置这些配置写在settings.json的languages键下。languages: { Python: { tab_size: 4, formatter: language_server, format_on_save: on }, JavaScript: { tab_size: 2, formatter: { external: { command: prettier, arguments: [--stdin-filepath, {buffer_path}] } } } }常用语言设置项以下为文档列出的可定制设置项详细参考 all-settings设置项说明源码默认值tab_size每级缩进对应的空格数4范围 1–128formatter使用的格式化工具autoformat_on_save保存时是否自动格式化onenable_language_server是否启用语言服务器truehard_tabs缩进使用制表符而非空格falsepreferred_line_length推荐的最大行宽80soft_wrap长行软换行方式noneshow_completions_on_input输入时是否弹出补全trueshow_completion_documentation补全菜单中是否显示文档truecolorize_brackets用 tree-sitter 括号查询为括号着色rainbow bracketsfalse上述默认值来自设置定义源码 LanguageSettingsContent其中每个字段都标注了Default注释可与文档互相印证。从源码结构看语言设置的结构体AllLanguageSettingsContentlanguage.rs把三类字段扁平化到同一层配置里defaults顶层语言设置#[serde(flatten)]展开、languages各语言的设置映射以及file_types文件扩展名关联。这意味着语言名之外的所有语言字段都可以直接写在settings.json顶层作为所有语言的默认值——这正是下一节顶层语言设置的原理。这些设置让你在不同语言、不同项目之间保持特定的编码风格。三、文件关联file_typesZed 默认根据扩展名自动识别文件类型但你可以通过file_types设置自定义关联规则file_types: { C: [c], TOML: [MyLockFile], Dockerfile: [Dockerfile*] }该配置让 Zed把.c文件当作 C 而不是 C 处理把名为MyLockFile的文件识别为 TOML对任何以Dockerfile开头的文件应用 Dockerfile 语法。值支持 glob 模式如Dockerfile*可以灵活处理复杂的项目命名约定。在源码中file_types的类型为FileTypeMaplanguage.rs即语言名 → 扩展名/文件名集合的映射。四、管理语言服务器语言服务器是 Zed 智能编码能力的核心提供自动补全、跳转定义、实时错误检查等能力。语言服务器是什么语言服务器实现了 LSP 协议标准化了编辑器与语言工具之间的通信使 Zed 无需为每种语言单独实现这些能力。关键功能包括代码补全Code completion错误检查与诊断Error checking and diagnostics代码导航跳转定义、查找引用代码操作重命名、提取方法Hover 悬停信息工作区符号搜索Workspace symbol search自动下载与存储位置Zed 简化了语言服务器的管理工作自动下载打开匹配文件类型的文件时Zed 会自动下载对应的语言服务器对已知文件类型Zed 可能会提示你安装相应的扩展存储位置macOS~/Library/Application Support/Zed/languagesLinux$XDG_DATA_HOME/zed/languages、$FLATPAK_XDG_DATA_HOME/zed/languages或$HOME/.local/share/zed/languages自动更新Zed 会保持语言服务器为最新确保获得最新特性与改进。多个语言服务器的优先级选择language_servers部分语言在 Zed 中有多个语言服务器可选。你可能同时安装了打包语言服务器的多个扩展导致同一语言存在能力重叠。language_servers设置让你控制使用哪个语言服务器以及先后顺序languages: { PHP: { language_servers: [intelephense, !phpactor, !phptools, !phpantom, ...] } }该示例中intelephense被设为首选语言服务器phpactor、phptools、phpantom被禁用注意!前缀...展开为该语言注册表中尚未列出的其余语言服务器。...是一个通配符你按名字列出的服务器保持其位置不变...在该位置填入剩余的服务器带!前缀的服务器被完全排除。因此当新安装了语言服务器扩展、或为该语言注册了新服务器时...会自动将其包含进来。如果你希望完全掌控启用哪些服务器就不要写...——只有你显式列出的服务器会被使用。从源码看这一语法由ConfiguredLanguageServer结构实现language.rs常量REST_OF_LANGUAGE_SERVERS的值就是字符串...而!前缀在反序列化时被解析为disabled: true字段单元测试 test_configured_language_server_serialization 验证了!rust-analyzer与禁用状态之间的互转。Ruby 示例覆盖是整体替换而非合并假设你在处理 Ruby。默认配置如下{ languages: { Ruby: { language_servers: [ solargraph, !ruby-lsp, !rubocop, !sorbet, !steep, !kanayago, !fuzzy-ruby-server, ... ] } } }当你在自己的设置中覆盖language_servers时你的列表会整体替换默认列表。这意味着像kanayago这样默认被禁用的服务器会被...重新启用除非你在自己的配置中再次显式禁用它。配置结果[...]solargraph、ruby-lsp、rubocop、sorbet、steep、kanayago、fuzzy-ruby-server[ruby-lsp, ...]ruby-lsp、solargraph、rubocop、sorbet、steep、kanayago、fuzzy-ruby-server[ruby-lsp, !solargraph, !kanayago, ...]ruby-lsp、rubocop、sorbet、steep、fuzzy-ruby-server[ruby-lsp, solargraph]ruby-lsp、solargraph注意第一个示例中...包含了kanayago尽管它默认是禁用的。因为覆盖替换了默认列表原来的!kanayago条目已不存在。要保持其禁用状态必须在自己的配置中显式写入!kanayago。这个整体替换语义在源码中有专门的测试保障test_language_servers_merge_keeps_per_language_lists_pure 断言per-language list must replace the older one wholesale语言级列表必须整体替换旧列表而 test_user_per_language_config_overrides_default_disables 则验证了用户按语言名列出服务器时可以解除默认禁用——与文档表格的行为完全一致。顶层语言设置每个语言设置项也可以写在settings.json顶层languages映射之外。顶层条目是所有语言的默认值语言级的取值总是整体替换顶层取值二者永远不会合并。这与源码中的合并实现相互印证AllLanguageSettingsContent::merge_from 先把语言级设置与defaults合并用户全局设置覆盖默认值再让用户按语言的设置覆盖同名语言的已有设置。工具链Toolchains一些语言服务器需要配置当前的工具链即某特定版本的编程语言编译器和/或解释器安装可能还包括项目的完整依赖集。Zed 认为工具链的例子包括 Python 的虚拟环境。并非所有语言都支持工具链发现与选择支持的可以通过工具链选择器toolchain::Select动作指定。更多细节见 toolchains。配置语言服务器lsp在settings.json中配置语言服务器时自动补全建议会列出 Zed 识别的全部可用 LSP 适配器而不仅仅是当前已加载语言激活的那些——这方便你在打开相关文件之前就进行配置。许多语言服务器接受自定义配置项可以写在lsp段中lsp: { rust-analyzer: { initialization_options: { check: { command: clippy } } } }该示例让 Rust Analyzer 在保存文件时额外使用 Clippy 进行 Lint。从源码看lsp段的类型是LspSettingsMapproject.rs即服务器名 →LspSettings的映射LspSettingsproject.rs包含binary、initialization_options、settings、enable_lsp_tasks与fetch字段。嵌套对象写法配置语言服务器选项时应使用嵌套对象而不是点分隔字符串这对复杂配置尤其重要。以 TypeScript 语言服务器为例假设你要启用严格空值检查将目标 ECMAScript 版本设为 ES2020。正确的写法是lsp: { typescript-language-server: { initialization_options: { // 以下不支持VSCode 点式风格 // preferences.strictNullChecks: true, // preferences.target: ES2020 // // 以下写法正确嵌套写法 preferences: { strictNullChecks: true, target: ES2020 } } } }可能的配置项不同语言服务器使用不同的配置方式initializationOptions在语言服务器启动时发送一次修改后需要重启服务器才能生效。rust-analyzer 与 clangd 就只依赖这种配置方式lsp: { rust-analyzer: { initialization_options: { checkOnSave: false } } }Configuration Requestworkspace/configuration服务器可以多次查询大多数服务器只依赖这种配置方式lsp: { tailwindcss-language-server: { settings: { tailwindCSS: { emmetCompletions: true } } } }除 LSP 相关的服务器配置项外Zed 中还允许为某些服务器自定义二进制的启动方式。语言服务器默认会自动下载或在 PATH 中找到后直接启动如要指定显式的备用二进制可以在设置中声明lsp: { rust-analyzer: { binary: { // 是否从网络获取二进制而非尝试在本地查找 ignore_system_version: false, path: /path/to/langserver/bin, arguments: [--option, value], env: { FOO: BAR } } } }对应源码中的BinarySettingsproject.rspath、arguments、env、ignore_system_version四个字段与上述示例一一对应。启用或禁用语言服务器可以按语言开关语言服务器支持languages: { Markdown: { enable_language_server: false } }这禁用了 Markdown 文件的语言服务器对大型文档项目来说有利于性能。可以写在~/.config/zed/settings.json全局也可以写在项目目录的.zed/settings.json中项目级。五、格式化与 LintZed 支持代码格式化与 Lint用于保持代码风格一致、尽早发现问题。配置格式化器formatterZed 同时支持内置与外部格式化器详见formatter。可以在settings.json中全局或按语言配置languages: { JavaScript: { formatter: { external: { command: prettier, arguments: [--stdin-filepath, {buffer_path}] } }, format_on_save: on }, Rust: { formatter: language_server, format_on_save: on } }该示例对 JavaScript 使用 Prettier、对 Rust 使用语言服务器自带的格式化并都设为保存时格式化。要禁用某语言的保存格式化languages: { Markdown: { format_on_save: off } }从源码看formatter的类型是FormatterListlanguage.rs可以是单个Formatter或其数组多个格式化器按声明顺序依次执行Formatter枚举language.rs的合法取值包括auto默认优先使用 Zed 的 Prettier 集成如适用否则回退到语言服务器格式化none不格式化prettier使用 Zed 的 Prettier 集成external外部命令含command与可选的argumentscode_action字符串通过语言服务器执行指定 code action 来格式化language_server使用语言服务器格式化可简写为字符串language_server也可写为{language_server: {name: ruff}}指定特定服务器对应LanguageServerFormatterSpecifier::Specific。反序列化测试 test_formatter_deserialization 验证了这些写法的解析结果例如{formatter: language_server}解析为当前语言服务器格式化器。format_on_save的完整取值为FormatOnSave枚举language.rson保存时格式化整个文件默认off不格式化modifications只格式化含未暂存改动的行要求版本控制可用且 LSP 支持 range formatting否则跳过modifications_if_available只格式化未暂存改动的行但 git diff 不可用或 LSP 不支持 range formatting 时回退为整文件格式化。配置 LinterSetting Up LintersZed 中的 Lint 通常由语言服务器完成许多语言服务器允许自定义 Lint 规则lsp: { eslint: { settings: { codeActionOnSave: { rules: [import/order] } } } }该配置让 ESLint 在保存 JavaScript 文件时自动整理 import 顺序。要在保存时自动运行 Linter 修复使用code_action格式化器languages: { JavaScript: { formatter: { code_action: source.fixAll.eslint } } }格式化选区Format SelectionsZed 支持只格式化选中的文本通过editor::FormatSelections动作触发。行为取决于配置的格式化器只有当活动格式化器确实能为至少一个选中缓冲区做 range 格式化时该动作才会出现Language server为每个选区发送 LSP range formatting 请求这是最精确的仅选区格式化方式仅当配置的语言服务器声明支持 range formatting 时才可用Prettier使用 Prettier 内置的 range formatting 格式化覆盖所有选区的最小范围落在选区之外的编辑会被丢弃从而只改动选中代码External 命令外部命令格式化器不支持 range 格式化格式化选区时会被跳过Code action 格式化器code action 作用于整个缓冲区因此不会单独启用 format selections。组合使用格式化与 LintZed 允许在保存时同时执行格式化和 Lint。例如对 JavaScript 用 Prettier 格式化 ESLint 修复借助formatter的数组形式按顺序执行languages: { JavaScript: { formatter: [ { code_action: source.fixAll.eslint }, { external: { command: prettier, arguments: [--stdin-filepath, {buffer_path}] } } ], format_on_save: on } }排障Troubleshooting遇到格式化或 Lint 问题时查看 Zed 的日志文件中的错误信息命令面板执行zed::OpenLog确认外部工具格式化器、Linter已正确安装并位于 PATH 中检查 Zed 设置与语言自身的配置文件如.eslintrc、.prettierrc两处配置是否一致。六、语法高亮与主题Zed 提供语法高亮与主题的自定义能力用于定制代码的视觉呈现。自定义语法高亮Zed 使用 Tree-sitter 文法做语法高亮。通过theme_overrides设置可以覆盖默认高亮。下面的示例把注释设为斜体、并把字符串颜色改掉theme_overrides: { One Dark: { syntax: { comment: { font_style: italic }, string: { color: #00AA00 } } } }选择与自定义主题更换主题有两种方式使用主题选择器theme_selector::Toggle动作或在settings.json中直接设置theme: { mode: dark, dark: One Dark, light: GitHub Light }在~/.config/zed/themes/下创建 JSON 主题文件即可创建自定义主题Zed 会自动发现并可用。使用主题扩展Zed 支持主题扩展可通过扩展面板zed::Extensions动作浏览和安装。若要开发自己的主题扩展参见 Developing Theme Extensions 指南。七、使用语言服务器特性语义 TokenSemantic Tokens语义 token 利用语言服务器提供的类型与作用域信息提供更丰富的语法高亮。通过semantic_tokens设置启用semantic_tokens: combinedoff— 仅使用 Tree-sitter 高亮默认combined— LSP 语义 token 叠加在 tree-sitter 高亮之上full— LSP 语义 token 完全替换 tree-sitter 高亮。可以通过设置中的global_lsp_settings.semantic_token_rules自定义 token 的颜色与样式其完整文档见 Semantic Tokens。从源码看semantic_token_rules对应GlobalLspSettingsContentproject.rs中的SemanticTokenRules字段每条SemanticTokenRuleproject.rs可指定token_type、token_modifiers、style、foreground_color、background_color、underline、strikethrough、font_weight与font_style。仓库还附带了默认规则文件 default_semantic_token_rules.json 可作参考。同文件中还可配置request_timeoutLSP 响应超时默认 120 秒0表示不超时与max_buffer_line_length超过该行长的缓冲区将整体禁用 LSP 特性默认 20000用于大型文件场景下的性能控制。Inlay Hints内联提示Inlay hints 在代码行内提供额外信息例如参数名或推断出的类型。在settings.json中配置inlay_hints: { enabled: true, show_type_hints: true, show_parameter_hints: true, show_other_hints: true }语言级的 inlay hint 设置请参考各语言的文档。对应源码InlayHintSettingsContentlanguage.rs还支持show_value_hints调试时内联显示值默认true、show_background默认false、edit_debounce_ms默认 700、scroll_debounce_ms默认 50以及toggle_on_modifiers_press按住指定修饰键时临时切换提示。Code Actions代码操作Code actions 提供快速修复与重构选项。通过editor::ToggleCodeActions命令访问或点击光标旁出现的灯泡图标。跳转定义与查找引用使用以下命令在代码库中导航editor::GoToDefinitionf12editor::GoToTypeDefinitionmacOS 为cmd-f12其他平台为ctrl-f12editor::FindAllReferencesshift-f12重命名符号Rename Symbol跨项目重命名符号的步骤将光标置于符号上执行editor::Rename命令f2输入新名称并回车。这些特性都依赖各语言语言服务器的能力。当重命名的符号跨多个文件时Zed 会在 multibuffer 中打开一个预览让你审阅整个项目中的所有改动后再应用保存该 multibuffer 即确认重命名若想放弃可以撤销改动或不保存直接关闭 multibuffer。Hover 悬停信息使用editor::Hover命令显示光标下符号的信息通常包括类型信息、文档以及相关链接。工作区符号搜索project_symbols::Toggle命令允许在整个项目中搜索符号函数、类、变量对快速定位大型代码库非常有帮助。代码补全Zed 在输入时提供智能补全建议也可用editor::ShowCompletions命令手动触发再用tab或enter接受建议。诊断Diagnostics语言服务器在你编码时提供实时诊断错误、警告、提示。使用diagnostics::Deploy命令查看项目中的所有诊断。八、小结Zed 的语言配置围绕三个层次展开languages映射按语言覆盖缩进、软换行、格式化、补全、语义 token 等行为顶层同名字段则作为所有语言的默认值语言级取值整体替换顶层取值、二者不合并file_types映射用扩展名或文件名 glob 决定文件归属的语言lsp映射按服务器名配置initialization_options启动时一次性下发修改需重启、settings可被服务器多次查询以及binary本地二进制的路径、参数与环境变量。配合language_servers中!前缀禁用与...通配其余已注册服务器的列表语法可以在多个语言服务器并存的扩展生态中精确控制优先级。所有上述配置项的定义与默认值均可在 crates/settings_content/src/language.rs 与 crates/settings_content/src/project.rs 中查证配套的 JSON Schema 也可用于编辑器校验你的settings.json。【免费下载链接】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),仅供参考
返回列表