zed-industries / zed

Code at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
https://zed.dev
Other
39.31k stars 2.04k forks source link

[Extensions] Per-file language server #12428

Open deecewan opened 1 month ago

deecewan commented 1 month ago

Check for existing issues

Describe the feature

For sorbet for Ruby, the language server needs exactly 1 input directory. This is the directory that contains the sorbet/ directory (and by extension, the config).

if I have a project that looks like this, for instance:

root/
  api/
    sorbet/
    some-file.rb
  ui/
    index.js

when I open root/ in Zed, it will start the language server with the cwd set to root/. The problem is, is that Sorbet doesn't find a sorbet/ directory there, so errors. Per-project, I could set a config value to say "load api/" and then update the extension to launch the LSP correctly for that directory. But there's no way to check that, for the file I'm looking at, where that directory should be.

Also, if I have a project that looks like this:

root/
  service-one/
    sorbet/
    some-file.rb
  service-two/
    sorbet/
    some-file.rb

I can't start language servers for both, because a language server is based solely on a root, and there's no way to set config in that case, because it'd need two different values at the same time.

Ideally, I'd like to be able to get the file I'm looking at, and return a language server for that file. In the first instance, I'd get the ruby file, and return a root of root/api. In the second, I'd start 2 servers with unique IDs, and have the IDs cached (somehow...). Then for every file that is opened, my extension can start (or return) a language server that should handle that file.

This is pretty much how neovim supports language servers right now, where the plugin is asked about each file, instead of the language as a whole.

Somewhat relatedly, even if I did set the root/api dir for the first case, Sorbet doesn't return fully-qualified files. Rather, it returns file names relative to the root/api/. When Zed tries to open them (say, for "Go to definition"), the file doesn't exist. It returns some-file.rb instead of api/some-file.rb, for instance.

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

No response

timothyshrugged commented 4 days ago

Just out of curiosity: how are you getting Sorbet to work with Zed in the first place?

deecewan commented 2 days ago

@timothyshrugged i created a custom plugin that implemented the LSP plugin interface for zed. Then just called the sorbet language server underneath that.