插件作者文档

如果您通过编写编辑器插件将 gopls 集成到编辑器中,那么编辑器和 gopls 之间的通信语义有相当一部分并未在 LSP 规范 中进行说明。

我们在此尝试记录这些细节以及对其他插件作者有帮助的任何其他信息。

如果您正在自己实现插件,并且有本页面未解答的问题,请联系我们提问,然后也请将您的发现贡献回本页面。

支持的功能

在大多数情况下,您应该查看 功能索引 来了解 gopls 是否支持某项功能。

要获得真正权威的答案,您应该查看 initialize 请求的 结果,其中 gopls 在 ServerCapabilities 中列出了其支持情况。

位置和范围

许多 LSP 请求会传递位置或范围信息。这在 LSP 规范 中有描述。

文档中的一个位置(参见下面的 Position 定义)表示为一个基于零的行和字符偏移量。偏移量基于 UTF-16 字符串表示。因此,像 a𐐀b 这样的字符串,字符 a 的字符偏移量是 0,字符 𐐀 的字符偏移量是 1,字符 b 的字符偏移量是 3,因为 𐐀 在 UTF-16 中用两个代码单元表示。

这意味着集成者需要计算基于 UTF-16 的列偏移量。请使用 protocol.Mapper 进行所有转换。

编辑

为了将 gopls 的更改传达给编辑器,LSP 在响应中支持 TextEdit 数组,这些 TextEdit 的定义在 TextEdit 中。规范精确说明了如何应用这些 TextEdit

所有文本编辑的范围都引用原始文档中的位置。文本编辑的范围绝不能重叠,这意味着原始文档的任何部分都不能被多个编辑进行修改。但是,多个编辑可以具有相同起始位置:多个插入,或任意数量的插入后跟单个删除或替换编辑。如果多个插入具有相同的位置,则数组中的顺序定义了插入的字符串在结果文本中出现的顺序。

所有 []TextEdit 都经过排序,以便反向应用接收到的增量数组可以实现符合规范的期望结果。

Errors

各种错误代码在 LSP 规范 中进行了描述。我们仍在确定一个方法返回错误意味着什么;错误是否仅用于低级 LSP/传输问题,还是其他情况也会导致返回错误?有关此问题的讨论,请参见 #31526

目前选择的方法受到当前流行的编辑器集成中实际处理方式的影响。它很可能会发生变化,并且理想情况下会跨请求变得更加一致。

文件监控

gopls 所依赖的文件在其关联的编辑器外被修改是很常见的情况。

例如,进行正确类型检查所需的文件会在切换 git 分支时被修改,或者会被代码生成器更新。

直接监控 gopls 内部的文件存在许多棘手的问题,但 LSP 规范 提供了允许 gopls 请求客户端通知其文件系统更改的方法,特别是 workspace/didChangeWatchedFiles。目前,社区成员正在 gopls 中添加此功能,该功能已在 #31553 中跟踪。


本文档的源代码可以在 golang.org/x/tools/gopls/doc 下找到。