microsoft / language-server-protocol

Defines a common protocol for language servers.
https://microsoft.github.io/language-server-protocol/
Creative Commons Attribution 4.0 International
11.08k stars 772 forks source link

Please revisit the idea of exposing the configuration format as JSON schema #1640

Open idanarye opened 1 year ago

idanarye commented 1 year ago

Long ago I've suggested to add methods for clients to get the current configuration and a schema for the configuration (#467). This was closed as out of scope, and the main objection (as I understand it) was that JSON a generic client won't be able to do anything useful with that information.

Now that the ecosystem is a bit more mature, I request that you look again at the idea. JSON Schema seems to be the standard for specifying JSON structure, and has lots of tools and libraries. I can think of two ways to utilize it for this task - both done by the clients (the protocol and the servers just need to offer the schema and the configuration):

I. Language servers for data serialization formats

Language servers like vscode-json-languageservice or YAML Language Server can read a JSON Schema and use it to lint deviations from the schema, provide completion for the specific fields and their possible values, and show tooltips when hoovering on fields or values.

An editor or an IDE could:

  1. Get the current configuration from the language server.
  2. Serialize that configuration to JSON or YAML.
  3. Put that serialized configuration in a text buffer.
  4. Attach a language server to that text buffer.
  5. Get the configuration schema from the original language server, and feed it to the language server that handles the serialized configuration buffer.
  6. When the user is done editing the configuration, send it back to the original language server.

The user will be working on a full configuration - even if it's just the default one, it would still have all the fields because we got it from the server which means that's what the server uses internally. Working on something like that, together with a language server that helps you edit it, should be much easier than writing a configuration from scratch based on documentation and some examples.

II. UI generators

There are many libraries that can take a JSON Schema and generate UI for editing that schema. Most of them are web UIs, so this is mainly useful for editors/IDEs based on web technologies (like VSCode), but other editors can just use the first method.

This works the same as the previous method, but instead of using a language server for JSON/YAML the editor/IDE would use one of these libraries to generate a UI for editing the configuration.

dbaeumer commented 1 year ago

I still thing that most clients have their own setting story and that from an overall integration point of view it is better if the settings are fully integrated into the client UI then driven by the server.

VS Code for example comes with is own setting definition story (including JSON Schema for it) and a UI that allows you to edit the settings.

idanarye commented 1 year ago

VS Code for example comes with is own setting definition story (including JSON Schema for it) and a UI that allows you to edit the settings.

Yes, but that settings editing UI needs to be configured for each language server individually, so that it knows what fields and what options to offer and how to convert them to a JSON that can be fed to the language server. Most language servers do this by releasing a VSCode extension - but these only works for VSCode.

What I'm suggesting is that instead of burying the configuration schema deep inside the companion VSCode extension's package.json, it should be available explicitly via a LSP method, and all clients - not just VSCode - will have access to it.

I agree that each client should have their own setting story, but that story should be configurable by the server via a standard protocol. A client should not be responsible for configuring its settings editor individually for each server, and a server should not be responsible for separately configuring the settings editor of each client.

rchl commented 1 year ago
  1. VSCode extensions have to declare the schema up-front. Requesting from the server at runtime wouldn't work as Editor needs to know the settings before the server is started.

  2. VSCode extensions mix and match server settings with its own settings. For example settings that server expects through initializationSettings have to be mapped to custom settings in the extension (or similar in other editors).

I wouldn't mind servers telling me the schema of settings they support but that wouldn't really be usable as a replacement for package.json schema in extensions or as something that would help in automating things in other editors since it would require starting the server first which is a chicken and egg situation.

dbaeumer commented 1 year ago

From my experiences from ESLint the settings maintained in VS Code didn't match one to one with the once I provide to the server. I even think that it is better if a server specifies its settings and clients need to do the best to map them onto their settings story.

ogoffart commented 1 month ago

What I'm suggesting is that instead of burying the configuration schema deep inside the companion VSCode extension's package.json, it should be available explicitly via a LSP method, and all clients - not just VSCode - will have access to it.

As a language server author, I very much agree with this!

The server configuration is working well for vscode users (as we have it in the package.json of the vscode extension), but for all other editors, there is no way to communicate to the client what are the configuration options and expected values so that the editor can show a UI for them like vscode does.

  1. VSCode extensions have to declare the schema up-front. Requesting from the server at runtime wouldn't work as Editor needs to know the settings before the server is started.

Obviously, VSCode would have to be adapted to be able to query configuration through the LSP, and merge that in the configuration. I don't know VSCode codebase so i can't say if this is easy or difficult. But even if it wouldn't work in vscode, it would be nice to have it for other editors and keep a package.json for vscode anyway since vscode anyway needs a special extension.

  1. VSCode extensions mix and match server settings with its own settings. For example settings that server expects through initializationSettings have to be mapped to custom settings in the extension (or similar in other editors).

That's an issue in vscode, but this shouldn't block that protocol feature for other editors.

it would require starting the server first which is a chicken and egg situation.

The point of the configuration settings is that they are persistent. The first time you wouldn't have any configuration anyway. Then the client would send the settings that have been stored, regardless of the schema from the server.

I even think that it is better if a server specifies its settings and clients need to do the best to map them onto their settings story.

:+1:

dbaeumer commented 1 month ago

I am open for a request or a entry in the initialize response that described the expected result schema of a workspace/configuration request. However it must to 100% clear that this shouldn't be used to present a UI. As said, even in ESLint were I own the parts end to end the settings requested by the server don't match the settings / UI defined in the package.json file of the extension.

One additional thing to consider: settings are scoped so this needs to be supported by the schema as well.

idanarye commented 1 month ago

However it must to 100% clear that this shouldn't be used to present a UI

Why not? Sure, a hand-crafted UI will always look better, but a typical language server will only create one for one editor, maybe two. For the rest of the editors, wouldn't an auto-generated UI be better than no UI at all?