自定义语言服务器:如何使客户端将所有 *文件发送到服务器,而不仅仅是用户打开/编辑的文件?

发布于 2025-01-29 02:52:11 字数 660 浏览 5 评论 0原文

我正在努力实现自定义语言服务器和VSCODE语言扩展。我对客户端的起点是 lsp-sample。我的服务器实现完全是从头开始的,用不同的语言(不是JS)。

当前,我已经成功设置了textDocument/didopentextDocument/didChange将由客户端发送并由服务器接收的消息。 但是,我很难弄清楚如何同步 vscode工作区中的所有文件,而不仅仅是用户打开的那些文件。我找不到它在哪里在

例如,为了处理“ goto定义”请求,服务器需要了解其他文件中的定义,也许是从未打开或编辑的文件中的定义。

在服务器端,一个骇客的解决方案是为了解析工作空间的URI,然后手动加载一堆文件。但这似乎是LSP 应该支持的东西。也许我只是错过了它的记录。 (另外,感觉就像我会违反LSP设计的精神来在幕后进行类似这样的秘密操作,而无需与客户沟通。)

I'm working on implementing a custom language server and a VSCode language extension. My starting point for the client side is lsp-sample. My server implementation is entirely from scratch, in a different language (not JS).

Currently, I've successfully set up textDocument/didOpen and textDocument/didChange messages to be sent by the client and received by the server. However, I'm having trouble figuring out how to synchronize all files in the VSCode workspace, not just those that the user has opened. I can't find where this is supported in the protocol. The only text document synchronization capabilities I see are for documents opening, closing, and edits. What about all the other documents in the workspace?

For example, in order to handle "goto definition" requests, the server needs to know about definitions in other files, perhaps those that have never been opened or edited by the user.

A hacky solution would be, on the server side, to parse the URI of the workspace and just go load a bunch of files manually. But this seems like something that the LSP should support; perhaps I'm just missing where it's documented. (Also, it feels like I would be violating the spirit of the LSP design to do some covert ops like this behind the scenes, without communicating with the client.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

み格子的夏天 2025-02-05 02:52:11

单独的DidchangeWatchedFiles单独通知另一个答案所建议的不够,因为它仅在Create/Change/Delete的事件中通知您。

通常,在处理初始化请求。因此,这类似于您的想法。您可以使用initializeparams.workSpaceFolders获取VSCODE Workspace的URI,然后只使用您的服务器语言的文件系统API查找您的SRC文件,读取并执行您需要的任何初始化,然后再将响应返回到响应中客户。

这是示例来自Kotlin语言服务器。

之后,您可以依赖于随后在已经初始化了所有文件后处理更改。

这比您可以在服务器中实现文件系统观察器更好,但是您可以做到,但是 LSP协议不推荐出于多种原因。

服务器可以运行自己的文件系统观察机制,而不是依靠客户端提供文件系统事件。但是,由于以下原因,不建议这样做:

  • 在我们的经验中,请在磁盘上观看文件系统是具有挑战性的,尤其是如果需要在多个OS中支持它。
  • 文件系统观看不是免费的,特别是如果实现使用某种轮询并将文件系统树保存在内存中以比较时间戳记(例如,某些节点模块可以)
  • 客户端通常启动多个服务器。如果每个服务器都运行自己的文件系统,则可以成为CPU或内存问题。
  • 通常,服务器比客户端实现更多。因此,这个问题在客户端更好地解决了。

DidChangeWatchedFiles Notification alone as suggested by another answer isn't enough as it only notifies you in the events of Create/Change/Delete.

Generally, most servers that need to do what you're describing accomplish this by reading all source files in the server when handling the Initialize Request. So it's similar to what you're thinking. You can use InitializeParams.workspaceFolders to get the uri of the vscode workspace, and then just use your server language's file system apis to find your src files, read and do whatever initialization you need before returning a response to the client.

Here's an example from a kotlin language server.

After this, you can depend on DidChangeWatchedFiles Notification subsequently to handle changes after having already initialized all files.

This is better than implementing a file system watcher yourself in the server, which you could do, but is not recommended by the LSP protocol for several reasons.

Servers are allowed to run their own file system watching mechanism and not rely on clients to provide file system events. However this is not recommended due to the following reasons:

  • to our experience getting file system watching on disk right is challenging, especially if it needs to be supported across multiple OSes.
  • file system watching is not for free especially if the implementation uses some sort of polling and keeps a file system tree in memory to compare time stamps (as for example some node modules do)
  • a client usually starts more than one server. If every server runs its own file system watching it can become a CPU or memory problem.
  • in general there are more server than client implementations. So this problem is better solved on the client side.
终难愈 2025-02-05 02:52:11

也许您正在寻找

didchangewatchedfiles通知

请参阅规格

手表文件通知是从客户端发送到服务器的
当客户检测到更改对文件和文件夹的更改时
语言客户端(请注意,虽然名称建议只有文件事件
发送的是关于文件系统事件,该事件包括文件夹
出色地)。建议服务器为这些文件系统注册
使用注册机制的事件。在以前的实现中
客户在没有服务器的情况下推动文件事件。

基本上,客户端负责观看所需的文件,并在每次发生任何变化时向服务器发送通知。此时,服务器能够加载它们。

Perhaps you're looking for

DidChangeWatchedFiles Notification

See Specification

The watched files notification is sent from the client to the server
when the client detects changes to files and folders watched by the
language client (note although the name suggest that only file events
are sent it is about file system events which include folders as
well). It is recommended that servers register for these file system
events using the registration mechanism. In former implementations
clients pushed file events without the server actively asking for it.

Basically the client is responsible of watching the files you require and sends a notification to the server each time something changes on them. At this point the server is capable to load them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文