Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Providing primary/secondary language servers in an extension #15279

Closed
1 task done
vitallium opened this issue Jul 26, 2024 · 2 comments
Closed
1 task done

Providing primary/secondary language servers in an extension #15279

vitallium opened this issue Jul 26, 2024 · 2 comments
Labels
enhancement [core label] extension infrastructure Feedback for extensions APIs, creation, management, etc language server An umbrella label for all language servers potential extension Functionality that could be implemented as an extension (consider moving to community extensions)

Comments

@vitallium
Copy link
Contributor

vitallium commented Jul 26, 2024

Check for existing issues

  • Completed

Describe the feature

Hi, I would like to propose a small addition to extensions to give them a way to provide primary or secondary language servers. That sounds unusual because we used to work with a single language server per language: Ruby LSP for Ruby, rust-analyzer for Rust. There is one problem that happens from time to time - a single language server is not enough because various language servers, despite following LSP specification, can provide different results for the code. For example, for the Go language there is gopls language server that also provides formatting of the code but users also pick alternative options like gofmt (or even gofumpt) or goimports that provide the same LSP commands but with a different result. In order to achieve the best result for the end-user, it becomes a common scenario to use several language servers per single file.

Zed currently has built-in support for primary and secondary language servers but this API is not exposed. There are 2 built-in language servers that can be used as secondary: tailwind-language-server and eslint. I think it's a matter of time when users will ask about adding oxc or rome or biomejs as language servers. These servers act as linters (most of them) and adding them as primary language servers could conflict with existing primary language servers (#15023). I suspect this situation is not unique to JavaScript or Go.

It would be useful to have an ability to expose not only primary, but also secondary language servers in an extension. This is just a proposal, and I would like to propose the following:

  1. The extension manifest has the language_servers.<language_server_id> field, which defines a language server adapter, for instance, for the Ruby language:
[language_servers.ruby-lsp]
name = "Ruby LSP"
languages = ["Ruby"]
  1. To keep things simple, I think adding a new key called primary could be enough to indicate this particular language server is primary or not. This field is set to true by default, i.e. if field is missing from the language_server registration, treat it as true.
[language_servers.ruby-lsp]
name = "Ruby LSP"
languages = ["Ruby"]
primary = false

With primary field set to false, this language server will be registered as a secondary language server. Alternatively, to avoid confusion, instead of the primary field, there could be the secondary field which negates the idea of the primary field:

[language_servers.rubocop]
name = "rubocop"
languages = ["Ruby"]
secondary = true

All in all, this feature will allow extensions to provide secondary language servers, such as additional linters. Additionally, it could mean the extraction of tailwind and eslint language servers into their own extensions. I hope I've described this feature well enough, but if not, please let me know. Thank you!

If applicable, add mockups / screenshots to help present your vision of the feature

No response

@vitallium vitallium added admin read Pending admin review enhancement [core label] triage Maintainer needs to classify the issue labels Jul 26, 2024
@maxdeviant
Copy link
Member

Just as an FYI, we're not really trying to encode the primary/secondary language server concept.

This was something we did as a short-term solution, so it's unlikely it will be surfaced as part of the extension API.

@notpeter notpeter added potential extension Functionality that could be implemented as an extension (consider moving to community extensions) language server An umbrella label for all language servers extension infrastructure Feedback for extensions APIs, creation, management, etc and removed triage Maintainer needs to classify the issue admin read Pending admin review labels Jul 26, 2024
maxdeviant added a commit that referenced this issue Aug 1, 2024
…rimary language server (#15624)

This PR updates how we determine the "primary" language server for a
buffer to make it respect the order specified by the `language_servers`
setting.

Previously we were relying on the language servers to be registered in
the right order in order to select the primary one effectively.

However, in my testing I observed some cases where a native language
server (e.g., `tailwindcss-language-server`) could end up first in the
list of language servers despite not being first in the
`language_servers` setting.

While this wasn't a problem for the Tailwind or ESLint language servers
on account of them being defined natively with the designation of
"secondary" language servers, this could cause problems with
extension-based language servers.

To remedy this, every time we start up language servers we reorder the
list of language servers for a given language to reflect the order in
the `language_servers` setting. This ordering then allows us to treat
the first language server in the list as the "primary" one.

Related issues:

- #15023
- #15279

Release Notes:

- The ordering of language servers will now respect the order in the
`language_servers` setting.
- The first language server in this list will be used as the primary
language server.
@vitallium
Copy link
Contributor Author

Just as an FYI, we're not really trying to encode the primary/secondary language server concept.

This was something we did as a short-term solution, so it's unlikely it will be surfaced as part of the extension API.

Got it. Given also the discussion here #15597 I am going to close this issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement [core label] extension infrastructure Feedback for extensions APIs, creation, management, etc language server An umbrella label for all language servers potential extension Functionality that could be implemented as an extension (consider moving to community extensions)
Projects
None yet
Development

No branches or pull requests

3 participants