文章

OpenCode LSP 机制分析

OpenCode LSP 机制分析

OpenCode LSP 机制分析

一、LSP 的自动安装

OpenCode 为不同的编程语言自动配置相应的 Language Server Protocol(LSP)服务器。以 C/C++ 语言为例,系统会自动安装 clangd,默认安装路径为:

1
C:\Users\{用户名}\.local\share\opencode\bin\clangd_21.1.0\bin\clangd.exe

二、LSP 在 OpenCode 中的使用方式

2.1 自动错误诊断功能

当调用 writeedit 工具时,OpenCode 会自动提供 LSP 诊断信息,帮助识别和修复代码错误。系统会使用以下提示模板将诊断信息反馈给模型:

1
2
3
4
This file has errors, please fix
<file_diagnostics>
${limited.map(LSP.Diagnostic.pretty).join("\n")}${suffix}
</file_diagnostics>

实际使用的时候还得依赖LSP自身的能力,比如clangd这里如果没有建立索引,所有的诊断信息都是误报。

2.2 LSP 工具功能

要启用独立的 LSP 工具功能,需要设置环境变量:

1
export OPENCODE_EXPERIMENTAL_LSP_TOOL=true

启用后,LSP 工具将作为独立选项出现在模型的工具列表中:

工具名称lsp

工具描述: Interact with Language Server Protocol (LSP) servers to get code intelligence features.

支持的操作

  • goToDefinition:查找符号的定义位置
  • findReferences:查找符号的所有引用
  • hover:获取符号的悬停信息(文档、类型信息)
  • documentSymbol:获取文档中的所有符号(函数、类、变量)
  • workspaceSymbol:在整个工作区中搜索符号
  • goToImplementation:查找接口或抽象方法的实现
  • prepareCallHierarchy:获取位置处的调用层次项(函数/方法)
  • incomingCalls:查找所有调用指定位置函数的函数/方法
  • outgoingCalls:查找指定位置函数调用的所有函数/方法

必要参数

  • operation:要执行的 LSP 操作类型(枚举值见上文)
  • filePath:文件的绝对或相对路径
  • line:行号(基于 1,与编辑器显示一致)
  • character:字符偏移量(基于 1,与编辑器显示一致)

三、OpenCode存在的问题与限制

3.1 模型配置限制

OpenCode 在 Windows 平台上存在功能限制,无法配置自定义模型。这一问题在社区中有很多相关 Issue:

https://github.com/anomalyco/opencode/issues/631

3.2 终端输出乱码

使用 Ctrl+C 退出 OpenCode 时,终端会出现乱码输出。这是由于 OpenCode 使用的 Bun 框架存在问题,目前只能使用内置的 /exit 命令正常退出。相关讨论:

https://github.com/oven-sh/bun/pull/25876

3.3 工具功能对比

OpenCode 的工具列表与 Claude Code 的工具集高度相似:

以下是和opencode的对话,在明显要求使用lsp工具后, 默认情况下并不能直接调用起来lsp工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
你可以用lsp工具帮我找一下cmANON_OBJECT_HEADER_BIGOBJ这个结构体的定义吗?不要用grep等其他的工具

Thinking:用户要求我使用 LSP 工具来查找 cmANON_OBJECT_HEADER_BIGOBJ 这个结构体的定义,而不要使用 grep 等其他工具。

但是,我看了一下可用的工具列表,并没有 LSP 工具。可用的工具有:
- question
- bash
- read
- glob
- grep
- edit
- write
- task
- todowrite
- todoread
- skill
- webfetch

没有 LSP 工具。我应该告诉用户我没有 LSP 工具可用,然后询问他们是否想让我用其他方法来查找。

我目前没有可用的 LSP 工具。我可以使用其他方法帮你查找这个结构体的定义吗?

Build : clm=4.7 : 27.8s

3.4 Clangd 依赖问题

实际测试发现,clangd 在没有编译数据库(compile_commands.json)的情况下无法正常解析 C/C++ 代码。复杂项目中要实际使用LSP工具,就需要先生成编译数据库。

CMake on  master via 🅒 v4.2.1
> opencode debug lsp diagnostics Source/bindexplib.cxx
{
  "D:\\src\\github\\tools\\CMake\\Source\\bindexplib.cxx": [
    {
      "code": "pp_file_not_found",
      "message": "In included file: 'cmConfigure.h' file not found\n\nD:\\src\\github\\tools\\CMake\\Source\\bindexplib.h:5:10:\nnote: error occurred here",
      "range": {
        "end": {
          "character": 23,
          "line": 64
        },
        "start": {
          "character": 9,
          "line": 64
        }
      },
      "severity": 1,
      "source": "clang"
    },
    {
      "code": "unknown_typename",
      "message": "Unknown type name 'WORD'",
      "range": {
        "end": {
          "character": 6,
          "line": 104
        },
        "start": {
          "character": 2,
          "line": 104
        }
      }
    }
  ]
}

四、总结

OpenCode 宣称集成了 LSP,但是实际上在C/C++领域还是存在很多现实工程问题的,且它本身在windows上使用体验不太好,存在很多Bug,他的LSP的工具的描述,参数和 Cluade Code也是相差不大。

总的来说优缺点可以分为:

  • 优点:自动安装配置、读取和编辑的时候自动实时错误诊断、支持配置LSP作为可调用的工具
  • 待改进: 自定义模型配置不太行、Windows太多Bug、宣传效果小于实际效果。
本文由作者按照 CC BY 4.0 进行授权