文档

代码语义导航

lsp 工具让模型向语言服务器查询定义、引用、符号和调用层级,而不是靠搜索文本;模型改完文件后,服务器报告的错误和警告也会送回给它。Mework 会使用在 PATH 上找到的常见语言服务器,lsp.json 可以添加或替换服务器。

打开工具

这个工具在对话设置的工具页 文件与搜索 分组里,名为 代码语义导航(lsp)。内置的 mework 预设会打开它。它支持的操作和参数见 lsp 工具页。

语言服务器没有设置页,也不按对话选择:只要对话开了这个工具,就由认领该文件的服务器来回答。

Mework 自动发现的服务器

以下服务器的命令在 Mework 的 PATH 上时才会启用。

名称 命令 文件
rust-analyzer rust-analyzer .rs
typescript-language-server typescript-language-server --stdio .ts、.mts、.cts、.tsx、.js、.mjs、.cjs、.jsx
pyright pyright-langserver --stdio .py、.pyi
gopls gopls .go
clangd clangd .c、.h、.cpp、.cc、.cxx、.hpp、.hxx、.hh(需要 compile_commands.json)
lua-language-server lua-language-server .lua
bash-language-server bash-language-server start .sh、.bash

lsp.json

层级 文件
全局 ~/.mework/lsp.json(Windows:%USERPROFILE%\.mework\lsp.json)
工作区 <工作区>/.mework/lsp.json
{
  "lspServers": {
    "zls": {
      "command": "zls",
      "extensionToLanguage": { ".zig": "zig" }
    },
    "pyright": {
      "command": "basedpyright-langserver",
      "args": ["--stdio"],
      "extensionToLanguage": { ".py": "python", ".pyi": "python" }
    }
  }
}

这份文件添加了一个 Zig 服务器,其中的 pyright 条目替换了同名的内置服务器。格式与 Claude Code 插件声明语言服务器的格式相同。

  • 服务器名只能用 ASCII 字母、数字、- 和 _。
  • 文件不是合法 JSON,或者服务器没有写在 lspServers 下时,整份文件都会被忽略。文件开头带 UTF-8 字节顺序标记(BOM)没有关系。单个条目有错时只拒绝这一条,文件其余部分照常生效。
键 作用 默认值
command 必填。要启动的程序,直接运行,从不经过 shell。参数请写进 args;绝对路径里可以有空格。 —
extensionToLanguage 必填,不能为空。把文件扩展名映射到发给服务器的语言 id(rs、.rs、.RS 视为相同)。服务器负责哪些文件,只由这张表决定。 —
args 参数,字符串数组。 无
env 在 Mework 完整环境的基础上,为这个服务器额外设置的变量。 无
initializationOptions 服务器启动时发给它。 {}
settings 服务器的设置,启动后发送,服务器来要时也会提供。 无
workspaceFolder 服务器建立索引的文件夹,用绝对路径。 对话的工作区
startupTimeout 允许服务器启动的毫秒数。 30000
shutdownTimeout 允许服务器关闭的毫秒数。 5000
restartOnCrash 服务器崩溃时是否重启。 true
maxRestarts 最多重启几次。 3
diagnostics 设为 false 时不再报告错误和警告,导航照常可用。 true
description 对服务器的说明。 无
transport 只支持 "stdio"。 "stdio"

command、args、env 的值和 workspaceFolder 里的 ${VAR} 与 ${VAR:-默认值} 会用 Mework 的环境变量替换。变量未设置又没有默认值时,条目被拒绝。

哪个服务器回答

按以下顺序查找,第一个认领该文件扩展名的服务器负责回答:

  1. 工作区的 lsp.json;
  2. ~/.mework/lsp.json;
  3. 内置服务器。

同一份文件里如果有两个服务器认领同一个扩展名,写在前面的那个生效。名称与较低层级重复的条目会整个替换掉那一条,包括它的扩展名。

启动与改动

  • 服务器在第一次调用它负责的文件时启动。它建立索引期间,最初几次回答可能很慢或为空。
  • 每台机器、每个文件夹、每个名称只运行一个服务器,该工作区里的所有对话共用,一直运行到 Mework 退出。
  • 对 lsp.json 里某个服务器条目的修改,在下一次 lsp 调用时生效:配置改过的运行中服务器会按新设置重启,启动失败的服务器在配置改动后会重新尝试启动。
  • 每个请求限时 30 秒,不受 startupTimeout 影响。
  • 启动失败时,错误信息里带有服务器写到 stderr 的最后一行。

编辑后的诊断

write 或 edit 改动了某个正在运行的服务器已经打开的文件后,Mework 会把改动告诉服务器。编辑本身不会启动服务器。

服务器针对这个文件夹报告的新问题(错误、警告、信息和提示;无论是刚编辑的文件还是其他文件)会在模型下一步之前送达,时间线上显示为 送达了语言服务器诊断 卡片。

  • 每个问题只报告一次,每个文件最多 10 条,总共最多 30 条。
  • 只有对话打开了 write 或 edit 时才会送达诊断。
  • 在服务器条目里写 "diagnostics": false 可以关闭该服务器的诊断。

审批

lsp 调用视为读取 filePath:

  • 在工作区内从不询问;在工作区外,只有 手动 级别会询问。
  • 如果工作区有自己的 .mework/lsp.json,每次 lsp 调用在 手动 和 允许编辑 下都会询问,因为这个文件可以启动任意程序。
  • ~/.mework/lsp.json 和内置服务器不会增加审批卡。
  • 审批卡提供 总是允许。

参见安全级别。

限制

  • 超过 10 MB 的文件会被拒绝。
  • 在 Git 忽略的文件里的结果,不会出现在定义、引用、实现和工作区符号搜索的结果中。

远程机器

WSL 或 SSH 机器上的工作区,语言服务器在那台机器上运行,配置也从那里读取:依次是工作区的 .mework/lsp.json、远程用户主目录下的 ~/.mework/lsp.json,以及在那台机器 PATH 上找到的内置服务器。本机的 lsp.json 不会用到。

排查问题

调用失败,说没有能处理这种文件的语言服务器。 安装一个内置服务器,让它的命令出现在 PATH 上;或者在 lsp.json 里为这个扩展名添加条目。

最初几次调用什么都没返回。 服务器还在建立索引,稍后再试。clangd 还需要 compile_commands.json。

缺少某个定义或引用。 它可能在 Git 忽略的文件里。

诊断始终没有送达。 检查 write 或 edit 是否打开、服务器是否已经在运行(对该文件做任意一次 lsp 调用就会启动它),以及 diagnostics 是否设成了 false。

每次调用都要审批。 工作区里有 .mework/lsp.json(或旧的 .naiword/lsp.json)。

在 GitHub 上编辑本页