一个面向大型 Go 工程的 VS Code / Cursor 接口导航扩展。它在接口、接口方法和具体实现之间提供双向 CodeLens,同时使用轻量候选索引和按需 AST 校验兼顾响应速度与查找准确性。
不依赖 gopls,也不会在启动时构建整个工程的语法树。
工程特色
快速启动,按需精确查找
- 启动阶段只建立轻量的方法名候选索引,不扫描依赖目录,也不构建全工程 AST。
- 点击 CodeLens 后,仅解析接口所在包和可能包含实现的候选包。
- 优先使用接口中出现频率最低的方法缩小候选范围。
- 已完成的查询直接使用内存缓存,未变化的文件可从持久化 AST 缓存恢复。
Tree-sitter Go WASM 精确解析
扩展使用 Microsoft 维护的 @vscode/tree-sitter-wasm 0.3.1 和 Tree-sitter Go grammar,
不再包含自写 Go lexer 或语法解析器,也不通过 VS Code LSP API 或 gopls 查询实现。
每次解析都以单个 .go 文件为输入,提取紧凑的声明 IR 后立即释放 Tree-sitter Tree。
当前支持:
- Go 的隐式接口实现和完整方法签名校验。
- 值接收者、指针接收者及其不同的方法集。
- 本地或跨包嵌入的 struct、interface 和类型别名。
- 标准库接口、
go.mod锁定依赖、local replace、module replace 和 GOROOT 源码。 - import 别名、包内别名、跨包别名链和复合别名。
byte/uint8、rune/int32、any/interface{}等价关系,并尊重包级同名声明遮蔽。- 多行声明、分组参数、泛型接口与实现、泛型嵌入、泛型实例、匿名接口和嵌套函数类型。
- 泛型接口会跨完整方法集统一推导类型实参,并校验可解析的接口方法集约束;支持多个类型参数及其在复合类型中的嵌套、重复使用。
- 类型参数约束支持精确类型项、
~T、union、comparable、具名约束和依赖其他类型参数的约束;只能作为约束使用的接口本身仍不会显示 CodeLens。 - 指针、切片、数组、map、可变参数、channel、包限定类型和 Unicode 参数名的签名归一化。
- Go build tags、GOOS/GOARCH 文件约束和未保存编辑内容。
双向导航
implementations
type UserRepository interface {
→ implementations
FindByID(ctx context.Context, id string) (*User, error)
→ implementations
Save(ctx context.Context, user *User) error
}
← goto interface
func (r *PostgresUserRepository) FindByID(
ctx context.Context,
id string,
) (*User, error) {
// ...
}
implementations:查看完整实现该接口的类型,并跳转到类型声明。→ implementations:查看某个接口方法的实现,并跳转到具体方法。← goto interface:从接收者方法反向查找匹配的接口。
为大型工程控制开销
- 候选包 AST 使用 1-32 个 Worker Thread 并发解析,默认并发数为 16。
- 相同文件的并发解析请求会自动合并。
- 依赖接口只在工作区查找不到结果时按需搜索,不全量索引 module cache。
- 外部依赖中的 concrete type 不会混入工作区实现结果。
- 文件监听、未保存 overlay 和查询结果都支持增量失效。
- 支持 multi-root workspace,并保持同名包、同名接口和同名类型相互隔离。
VSIX 从锁定的上游版本原样携带 Tree-sitter JavaScript runtime、核心 runtime WASM、Go grammar WASM 和 MIT 许可证;依赖包里的其他语言 grammar 不会打进扩展。
使用方法
查看接口实现
- 打开包含 Go interface 的文件。
- 在
type InterfaceName interface上方点击implementations。 - 在 Quick Pick 中选择目标实现。
- 编辑器会跳转到对应 struct 或类型声明。
查看接口方法实现
- 打开包含 Go interface 的文件。
- 在目标方法上方点击
→ implementations。 - 选择具体实现。
- 编辑器会直接跳转到该方法的声明位置。
从实现跳转到接口
- 打开带接收者方法的 Go 文件,例如
func (s *Service) Run()。 - 点击方法上方的
← goto interface。 - 选择匹配的接口。
- 编辑器会跳转到接口声明。
查找结果会自动排除配置中的 mock、测试、生成文件和其他不需要的类型。
环境要求
- VS Code 1.76+,或兼容 VS Code 扩展的 Cursor 版本。
- 使用
.go文件;Go module 工程可以获得最完整的跨包和依赖解析能力。 - 实现匹配不依赖 gopls。解析 GOROOT 或 module cache 中的源码时,需要本机存在相应 Go 源码或依赖缓存。
配置
打开 VS Code / Cursor 设置并搜索 Go Interface Lens,或直接编辑 settings.json。
| 配置项 | 默认值 | 作用 |
|---|---|---|
goInterfaceLens.astConcurrency |
16 |
候选包 AST Worker 数量,可设置为 1-32 |
goInterfaceLens.excludedFolders |
mocks, mock, testdata, vendor |
排除指定目录 |
goInterfaceLens.excludedFilePatterns |
_mock.go, mock_, .pb.go, _test.go |
排除文件名中包含指定文本的文件 |
goInterfaceLens.excludedTypePatterns |
Mock, mock, Stub, Fake |
排除名称中包含指定文本的类型 |
goInterfaceLens.searchDependencies |
true |
反向查找无本地结果时,按需搜索依赖接口 |
goInterfaceLens.goModCache |
空 | 手动指定 Go module cache;为空时自动探测 |
示例:
{
"goInterfaceLens.astConcurrency": 16,
"goInterfaceLens.searchDependencies": true,
"goInterfaceLens.goModCache": "",
"goInterfaceLens.excludedFolders": [
"mocks",
"mock",
"testdata",
"vendor",
"generated"
],
"goInterfaceLens.excludedFilePatterns": [
"_mock.go",
"mock_",
".pb.go",
"_test.go",
".gen.go"
],
"goInterfaceLens.excludedTypePatterns": [
"Mock",
"mock",
"Stub",
"Fake"
]
}
类型名以 _ 开头时始终从实现结果中排除。
性能基线
开发环境中的合成测试包含 402 个 Go 文件:
- 启动候选索引约
47ms,Tree-sitter WASM 解析文件数为0。 - 首次 AST 查询约
37ms。 - 缓存查询约
0ms。 - 一次稀有方法查询只解析 2 个候选文件。
实际耗时取决于工程规模、磁盘、文件系统类型和候选方法的常见程度。
命令
| 命令 | 作用 |
|---|---|
Go: Show Implementations |
查看接口的完整实现 |
Go: Show Method Implementations |
查看接口方法实现 |
Go: Goto Interface |
从接收者方法跳转到接口 |
Go: Clear Implementation Lens Cache |
清除索引和查询缓存 |
前三个命令通常由对应 CodeLens 携带上下文调用。清理缓存命令可以直接从 Command Palette 执行。
常见问题
看不到 CodeLens
-
确认文件语言模式是 Go,且扩展已在当前本地或远程扩展宿主中启用。
-
在工作区
settings.json中显式启用 Go 文件的 CodeLens:{ "[go]": { "editor.codeLens": true } } -
确认接口本身不含
~int | ~string之类只能用于类型约束的类型集合;带类型参数但方法集可在运行时使用的泛型接口支持 CodeLens。 -
执行
Developer: Reload Window。 -
查看
Output -> Go Interface Lens和 Extension Host 日志。
[go].editor.codeLens 是 VS Code 兼容编辑器提供的 Go 语言模式设置,控制所有注册到 Go 文件的 CodeLens provider,并不表示本扩展依赖 Go 扩展或 gopls。即使工作区中没有这项配置,Trae、Cursor、远程设置、用户 Profile 或语言级配置也可能改变它的最终生效值;显式设为 true 可以避免这些配置层级关闭本扩展的 CodeLens。
CodeLens 显示较慢
VS Code 会并发请求同一 Go 文件上所有匹配的 CodeLens provider,并在编辑器侧合并结果后统一展示。Go Interface Lens 自己不调用 Go 扩展或 gopls,但官方 Go 扩展也是一个并列的 provider;当它等待 gopls 初始化或分析时,合并阶段可能延迟,本扩展已经生成的 CodeLens 也会稍后才显示或变为可点击。标准 CodeLens API 不提供 provider 优先级或独立渲染能力,因此本扩展无法绕过编辑器的聚合等待。
如果主要使用 Go Interface Lens 完成接口导航,推荐在设置中搜索 Go: Enable Code Lens(go.enableCodeLens),关闭官方 Go 扩展不需要的 CodeLens 总开关或子项,同时保留:
{
"[go]": {
"editor.codeLens": true
}
}
这样只是不再让官方 Go CodeLens 参与聚合,不会关闭本扩展,也不会禁用 gopls 的补全、诊断和普通代码跳转。不同版本的 Go 扩展可能将该设置显示为一个总开关或 references、run test 等多个子项,可以按实际需要全部关闭。
找不到实现
- 确认实现具有接口要求的全部方法及一致的参数、返回值类型。
- 检查值接收者和指针接收者的方法集差异。
- 检查排除目录、文件和类型配置。
- 执行
Go: Clear Implementation Lens Cache后重试。
依赖中的接口找不到
- 确认
goInterfaceLens.searchDependencies为true。 - 确认依赖出现在
go.mod中,或配置了有效 replace。 - 必要时通过
goInterfaceLens.goModCache指定 module cache 的绝对路径。
License
版本记录见 CHANGELOG.md。问题反馈请提交到 GitHub Issues。