
Crush LSP 集成指南3 行配置接上语言服务器让 AI 跨文件重命名不再翻车【免费下载链接】crushGlamourous agentic coding for all 项目地址: https://gitcode.com/gh_mirrors/crush3/crush一次改名的翻车现场你让 AI 把项目里一个叫contextPath的字段改成contextDir。它很卖力grep 了一圈逐处替换——然后它把一条注释里的contextPath、一段日志文案里的 contextPath、甚至测试里故意构造的字符串字面量也一起改了。反过来更糟真正参与逻辑的同名变量比如另一个包里恰好也叫这个名字的局部变量它又漏了。问题出在 AI 拿到的上下文是纯文本。grep 只认字面匹配分不清这是一个符号和这是句子里恰好出现的字符串。而你人肉改代码时靠的是什么是编辑器背后那套语言服务器它知道符号的定义在哪、引用在哪、重命名该波及哪些位置。LSPLanguage Server Protocol语言服务器协议就是编辑器与语言服务器之间的通用通信协议——gopls 之于 Go、typescript-language-server 之于 TS、nil 之于 Nix都是通过它给编辑器提供语义能力的。Crush 的做法很直接把同一套东西接给 AI让它像 IDE 一样看代码而不是像 grep 一样搜代码。官方 README 里对这一点的定位就是 LSP-Enhanced: Crush uses LSPs for additional context, just like you do。三行命令接上语言服务器 ️Crush 当前推荐的配置方式叫crushrc——一个基于 shell 语法的配置文件crush.json仍可用但官方已标记为弃用方向。在项目根目录的 crushrc 里加三行lsp add go --command gopls --env GOTOOLCHAIN go1.24.5 lsp add typescript --command typescript-language-server --args --stdio lsp add nix --command nil如果你还是习惯crush.json对应的写法是{ lsp: { gopls: { options: { staticcheck: true } } } }lsp add支持一批 flag日常用得着的主要是这几个--command指定语言服务器可执行文件--args传启动参数--env注入环境变量比如固定 Go 工具链版本--filetypes声明它负责的文件类型--root-markers声明看到这个文件就认定这里是项目根目录如go.mod、package.json--timeout设置初始化超时秒数。字段定义都在 配置结构体 里每个字段都带 jsonschema 描述编辑器里写配置时可以直接看提示。一个容易忽略的字段是timeout默认只有 30 秒。如果你接的是冷启动慢的服务器大型 monorepo 里的 gopls 很典型把它调到 60~120 秒否则初始化超时后这个服务器会被记为不可用——好在内部逻辑是 30 秒后允许重试不至于一次失败就彻底放弃。AI 拿到的不是更多文本而是一组新工具 接上 LSP 之后Crush 会向 agent 注册一组语言感知工具源码见 LSP 工具目录。按使用频率给你排个序lsp_rename——跨文件语义重命名。这是收益最大的一招它尊重作用域、重载和 import是真正的重命名而不是批量替换。工具描述里明确写了优先于手动多文件 edit。lsp_definition/lsp_references——找定义和找引用。前者会自动跳过注释、字符串和模糊匹配比 grep 精准得多AI 在改一个函数之前用它确认影响面。lsp_call_hierarchy——调用层级分谁调用了它和它调用了谁两个方向。重构前的 blast radius 分析就靠它。lsp_symbols——文档符号大纲。AI 接手一个陌生文件时先看结构再动手。diagnostics——拿到文件或整个项目的 LSP 错误、警告、提示。这意味着 AI 改完代码后能看到编译报错形成自查闭环而不是盲改。lsp_restart——诊断信息陈旧或服务器无响应时按名字重启某个或全部LSP 客户端。这是个很务实的设计后面会说到为什么需要它。注意一个行为细节这些工具只有在对应语言的 LSP 真正启动成功后才会注册。也就是说你不配置、或者二进制不在 PATH 里agent 就压根看不到这些工具不会假装能用语义能力。按需启动与几个踩坑点 ⚙️Crush 的 LSP 管理manager 实现是惰性启动的启动 Crush 并不会立刻拉起所有语言服务器而是当你操作到某个文件时才启动能处理该文件类型的服务器已经在跑的就是 no-op。好处是资源占用可控——你配了 5 个语言的服务器实际只启动当前碰到的那一个。配合惰性启动的是一套根目录识别机制auto_lsp选项默认开启Crush 会依据 root markers 自动判断项目边界。你手动配了--root-markers就按你配来的没配则走内置默认powernap 库里预置了一批常见语言。如果某台机器上语言服务器依赖缺失它会被标记 unavailable30 秒内不再重复尝试拉起避免疯狂重试刷日志。还有两个实操建议多客户端共享状态。两个指向同一工作目录的 Crush 客户端会加入同一个 workspace共享会话、权限队列和 LSP 状态。所以别担心开了两个终端语言服务器就翻倍。排障先开debug-lsp。加一行option debug-lsp true就能看到语言服务器初始化的详细日志——初始化超时、握手失败这类问题基本都能一眼定位。如果日志里服务器起来了但诊断总是旧闻直接用lsp_restart让它重来一次通常比重启整个 Crush 快。把语义能力用在刀刃上最后给一个心法把 LSP 工具当作 AI 的编译器和 IDE而不是让它永远开着干。日常提问、写文档这类任务用不到语义能力代价也很小惰性启动本来就不占资源但涉及跨文件重构、重命名、追调用链时确认对应语言的服务器已接上效果是质变——AI 的回答从我觉得这里大概也引用了这个名字变成这个符号在 4 个文件有 7 处引用重命名方案如下。完整的配置项清单可以直接翻 配置文档里面连lsp add的每条 flag 都有说明。接上它你的 AI 才算真正住进了你的代码库而不是站在门外往里猜。【免费下载链接】crushGlamourous agentic coding for all 项目地址: https://gitcode.com/gh_mirrors/crush3/crush创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考