CodeWhale LSP 扩展:如何用 [lsp.custom] 接入 Ruby、C# 等自定义语言服务器
【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale
CodeWhale 内置了一套 LSP 诊断管线:每次代理成功执行edit_file、apply_patch或write_file之后,引擎会向对应语言服务器请求诊断,并把结果作为一条合成系统消息注入会话消息流,让代理在下一轮 API 调用前就能看到编译/语法错误。内置注册表覆盖 Rust、Go、Python、TypeScript、Java、PHP、Vue、C/C++ 等语言,但 Ruby、C#、Swift、Lua 等语言不在内置Language枚举中。[lsp.custom]配置段就是为这些语言准备的:按文件扩展名注册任意 LSP 服务器,让 CodeWhale 在编辑.rb、.cs等文件后同样能拿到诊断。该功能自 v0.8.65 起可用(分支codex/lsp-php-custom-servers)。
功能触发机制与默认行为
配置之前先明确[lsp.custom]何时生效、失效时发生什么,这决定了你如何验证接入是否成功:
- 触发条件:仅在一次成功的文件编辑(
edit_file/write_file/apply_patch)之后触发。 - 路由逻辑:
LspManager::diagnostics_for先查内置注册表,只有当扩展名被识别为Language::Other时,才会回退检查用户的custom表——因此自定义配置是回退路径,不能覆盖内置语言(见下文限制)。 - 非阻塞失败模式:LSP 二进制缺失、服务器崩溃或轮询超时都只会跳过当轮诊断,不会阻塞代理。二进制缺失时每个扩展名仅记录一次警告,避免日志刷屏。
[lsp]段默认值:enabled = true;poll_after_edit_ms = 5000(等待publishDiagnostics的最长时间,毫秒);max_diagnostics_per_file = 20(按严重度排序后截断);include_warnings = false(默认只透出 error,即 severity 1;设为true才保留 warning)。- 运行时开关:可通过
/lsp on|off在会话中切换 LSP 行为。
以上默认值与触发路径来自 config.example.toml 中[lsp]段的注释和 crates/tui/src/lsp/mod.rs 的模块文档。
前提:语言服务器可执行文件在 PATH 中
[lsp.custom.<ext>]的command字段是要启动的可执行文件名,CodeWhale 通过 stdio 与它通信。文档对内置 PHP 的说明是“若intelephense在 PATH 中则默认启用”,自定义服务器的二进制若不在 PATH 中,行为就是上文描述的“缺失警告 + 跳过当轮诊断”。因此接入前先确保command指向的可执行文件(如ruby-lsp、csharp-ls、sourcekit-lsp)已安装且可在 PATH 中直接调用。
需要说明:项目文档没有给出这些第三方语言服务器的安装步骤,这里不替你补写安装命令;请确认你能在终端直接运行该可执行文件后再配置。
配置步骤:在 config.toml 中注册 [lsp.custom]
CodeWhale 的用户级全局配置默认位于~/.codewhale/config.toml(旧版~/.deepseek/config.toml仍作为回退被读取),工作区级配置位于<repo>/.codewhale/config.toml。[lsp]相关键的完整注释文档见 config.example.toml 的 LSP Diagnostics 段。
在配置文件中追加如下段落(示例取自 docs/LSP_PHP_CUSTOM.md,可按需只保留自己要用的语言):
[lsp.custom.rb] command = "ruby-lsp" args = ["--stdio"] language_id = "ruby" [lsp.custom.cs] command = "csharp-ls" language_id = "csharp" [lsp.custom.swift] command = "sourcekit-lsp" language_id = "swift"三个字段的含义以 crates/tui/src/lsp/mod.rs 中CustomLspDef的文档注释为准:
| 字段 | 必填 | 说明 |
|---|---|---|
command | 是 | 要启动的可执行文件(executable to spawn) |
args | 否 | 传给可执行文件的参数,默认空 |
language_id | 是 | LSPtextDocument/didOpen使用的languageId,必须与该语言服务器期望的值匹配 |
配置规则:
- 表键是文件扩展名,不含前导点:
[lsp.custom.rb]对应.rb文件。 - 扩展名匹配不区分大小写,
App.CS和App.Cs都会命中[lsp.custom.cs](见 crates/tui/src/lsp/mod.rs 中的测试)。 language_id写错不会导致启动失败,但会导致服务器在didOpen时收到不识别的语言标识,这是接入后“没有诊断”时最该核对的一处。
验证接入是否生效
运行时验证路径:在 CodeWhale 会话中对一个.rb文件执行一次编辑(例如让代理用edit_file修改它)。编辑成功后,引擎会向ruby-lsp发送didOpen/didChange,最多等待poll_after_edit_ms毫秒收集publishDiagnostics,命中的诊断会作为合成消息出现在会话中,代理能据此立即看到编译断点。如果始终拿不到诊断,按文档给出的失败模式逐项排除:可执行文件是否在 PATH(缺失时只有每扩展名一次警告)、服务器是否崩溃、是否超时的 5 秒轮询窗口。
如果你是 CodeWhale 的开发者,文档还给出了模块级验证命令:
cargo test -p codewhale-tui --bin codewhale-tui lsp:: # 32 tests passed (3 new: detects_php_extension, language_ids_for_php, # server_for_php_is_intelephense) cargo clippy -p codewhale-tui --bin codewhale-tui # lsp module: zero new warnings上面32 tests passed与zero new warnings是 docs/LSP_PHP_CUSTOM.md 中记录的文档示例结果,不代表你必须得到相同数量,测试数会随版本变化。
限制与边界
自定义配置是回退而非覆盖:即使你配置了
[lsp.custom.go],.go文件仍走内置gopls serve路径,自定义表只对内置注册表返回Other的扩展名生效(源码测试custom_fallback_only_for_other_language明确固化了这一行为)。要改内置语言的服务器,用[lsp.servers],例如把 PHP 换掉:[lsp.servers] php = ["phpactor", "language-server"]诊断透出受
max_diagnostics_per_file(默认 20)截断,且默认只含 error;需要 warning 时显式设置include_warnings = true。诊断注入只发生在 TUI 引擎的编辑成功之后;文档没有说明
exec/CLI 子命令路径会触发该管线,不要假设非交互场景同样生效。服务器崩溃或超时只影响当轮诊断,属于设计内的非阻塞降级,不需要当作故障处理。
继续深入
- 完整功能说明与改动清单:docs/LSP_PHP_CUSTOM.md(简体中文见 docs/zh_hans/LSP_PHP_CUSTOM.md)
- 配置键的完整注释:config.example.toml LSP Diagnostics 段
- 实现代码:crates/tui/src/lsp/mod.rs(
CustomLspDef、LspConfig)、crates/tui/src/lsp/registry.rs(内置语言注册表)
【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考