Language-server-protocol: Support notifying the server of which documents are visible in the client

Created on 23 Jun 2020  路  7Comments  路  Source: microsoft/language-server-protocol

This is slightly related to https://github.com/microsoft/vscode/issues/15178. Right now there's no way for an editor to know when a document is either "open" or "visible" in a way that matches the users expectation:

Open in this sense means it is managed by the client. It doesn鈥檛 necessarily mean that its content is presented in an editor.

There are many situations where a server would like to know what files a user has open (or visible). For example:

  • The user wants to ignore lints/errors in certain files - for example files generated by tools
  • When the user opens the file in the editor, they want to see these errors/lints (eg. to debug something going wrong in them)
  • When the user closes the file, they expect the errors/lints to disappear (immediately, not after 3 minutes)

Even though VS Code doesn't have an API for "open editors", it does have an API for "visible editors". Even if VS Code plans to never support "open editors" it would be very useful for LSP to provide "visible editors". On the other hand, if VS Code does add support for "open editors", then that could be provided instead/as well. In either case, it seems like LSP needs some changes to support one or the other (or both).

(as a workaround, I'm considering implementing custom messages in the VS Code extension + LSP server to pass the "visible editors" over to the server.. it feels really hacky though).

feature-request ui state

All 7 comments

I am very reluctant to sync UI state to the server. We really tried hard to not do this. I do see the problem with the diagnostics and the problem there is that it is a pure push model. So there are discussion to allow a pull model as well where this again would go back under the control of the editor. See https://github.com/microsoft/language-server-protocol/issues/737

And even using VS Code visible editor will not help since there is no API for the tab model (e.g. you don't want to see lint errors disappear for editors for which there is still an open tab).

Any objection to fold this with #737

I am very reluctant to sync UI state to the server. We really tried hard to not do this.

In Dart the server has a concept of "priority files". That means if there are multiple outstanding requests for multiple files, those that are marked priority are processed first. These are intended to be set to the visible (or at least open) files. Without allowing the server to know what files the user has open (or visible), this isn't possible (currently for non-LSP we use visible files and it works great - for LSP we have to use "open" files which is a bit wonky).

I do see the problem with the diagnostics and the problem there is that it is a pure push model. So there are discussion to allow a pull model as well where this again would go back under the control of the editor. See #737

This seems like it would increase server resources (especially if more things move to this model). Servers will have to start caching more data (or re-computing it frequently) if the client can ask for it at any time. The client is already caching it to show it in its UI - having the server able to tell the client when it changes feels like a better model to me.

That said - I'm not sure how it solves this issue. How does the server know whether to include the "excluded" file when the client asks for all diagnostics? (I'm assuming the client would ask for all, and not individually for each open file - as that would just lead to a lot of complaints - see https://github.com/microsoft/vscode/issues/13953).

And even using VS Code visible editor will not help since there is no API for the tab model (e.g. you don't want to see lint errors disappear for editors for which there is still an open tab).

Errors disappearing (for excluded files) when you tab to another file is a lot more understandable than randomly vanishing up to 3 minutes later (and perhaps even appearing when you don't have the file open, since didOpen makes no guarantees the user actually opened the file) :-)

To avoid caching on the server side we are looking into the concept of batch requests (see https://github.com/microsoft/language-server-protocol/issues/988).

The current concept in LSP is that it is under the clients control what data is visible and what data therefore need to be priorities.

And the concept of an open editor is not enough. A tool could for example show the outline inline in the file explorer and therefore the outline needs to be priorities. So if we let the server decide this then we need to let servers know about what is visible in the UI and what not in terms of LSP requests.

A tool could for example show the outline inline in the file explorer and therefore the outline needs to be priorities. So if we let the server decide this then we need to let servers know about what is visible in the UI and what not in terms of LSP requests.

That's true, but I was thinking about things that are pushed from the server (like errors) - if a user opens a project of 5000 files, the server needs to parse/lint them all, and doing the open files first is most useful.

I don't think batching helps the case I had in mind, which is the client asking the server for some data multiple times even if it hasn't changed. For example if the client asks the server for errors multiple times, the server has to either keep a cache of them, or re-compute them. Batching requests seems like it could prevent parsing the file multiple times for different requests, but I don't think it prevents requiring the server to keep copies of the data or re-compute them.

I also don't think this addresses the original need though - which is wanting to show errors for some files only when they're open. Even if the errors were pulled from the server, they would still persist when the file was closed unless there was some mechanism to tell the client only to show them while the file is open.

That's true, but I was thinking about things that are pushed from the server (like errors)

I agree with that case but it is the ONLY case in LSP where the server pushes. Everything else is pull. So instead of having a UI model sync for errors I would prefer having a pull model for errors.

And errors are not only presented in the editor. There are problem views and decorations in the file explorer.

I agree with that case but it is the ONLY case in LSP where the server pushes. Everything else is pull. So instead of having a UI model sync for errors I would prefer having a pull model for errors.

But doesn't pull mean the server has to invalidate everything on every change? If a user is typing inside a comment - with a push model, the server doesn't need to send any new errors, outline, code fixes, etc. - but if the client is pulling, it's going to keep asking for these and forcing the server to compute them (or keep a cache of them). And when the extension host is remote (Codespaces, etc.) it seems like the extra latency/slow round trips would make this worse?

That aside - I still don't think any of that addresses this need. Even in a pull model, it doesn't allow us to show errors for ignored files only while they're open.

https://github.com/microsoft/vscode-languageserver-node/issues/683 is a related issue. VS Code fires did-open events whenever a file is opened (which includes things like extensions opening them, or the hover preview when holding Ctrl/Cmd), which ends up at the LSP server and causes it to start analyzing files that have never been opened.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Khaos66 picture Khaos66  路  5Comments

kaloyan-raev picture kaloyan-raev  路  6Comments

ljw1004 picture ljw1004  路  3Comments

kittaakos picture kittaakos  路  4Comments

felixfbecker picture felixfbecker  路  3Comments