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
47.76k stars 2.79k forks source link

Use already installed language server if in `$PATH` #4978

Open diktomat opened 1 year ago

diktomat commented 1 year ago

Check for existing issues

Describe the feature

Instead of downloading a language server within Zed, I propose it should first look in $PATH if it's already installed and use that one instead. Beyond saving some space, this would also enable using different ls versions, via rustup or direnv (#1025) for example.

mrnugget commented 7 months ago

Beyond saving some space, this would also enable using different ls versions, via rustup or direnv (#1025) for example.

Since you mention direnv: I assume the idea is to check $PATH in the scope of the currently open project, right?

szlend commented 7 months ago

Since you mention direnv: I assume the idea is to check $PATH in the scope of the currently open project, right?

This is actually something I struggled with a lot in most GUI editors. If you have project A already open, and you open project B, that window will inherit the environment (including PATH) from the first project (A). This is because the second window usually reuses the same process, or forks off it.

I described some of these pitfalls in https://github.com/zed-industries/zed/issues/4977#issuecomment-1908639351

mrnugget commented 7 months ago

Yes, it's not that straightforward. We already do this:

https://github.com/zed-industries/zed/blob/98fff014da0033d7e1075908ee5ffd05f047b792/crates/zed/src/main.rs#L99-L106

What this does:

What I thought we could do: when we weren't started by a ClI and you open a project, we spawn the login shell in that project's directory and use that env.

But that is also a bit tricky since you can add projects to a window, you have to remember your "original" env and reset it when switching windows/projects, ... and it's not that obvious to users what the env is.

szlend commented 7 months ago

I think for this issue specifically, the way the env is loaded is fine, the language servers jut need to take PATH into account.

But for #4977 (direnv) support I would be happy to help figure out a good solution. Maybe worth moving the discussion there?

What I thought we could do: when we weren't started by a ClI and you open a project, we spawn the login shell in that project's directory and use that env.

I think that would probably cover most of the cases yeah. On the surface it sounds like a good idea to me.

But that is also a bit tricky since you can add projects to a window, you have to remember your "original" env and reset it when switching windows/projects, ... and it's not that obvious to users what the env is.

There's probably no good solution for that, unless you treat each project in the window kind of like its own window/sandbox. So each project runs its own language servers etc.

Though that still leaves the integrated terminal which is completely separate. If you use direnv, you would probably want the terminal to inherit the login environment, and let it apply its own environment overrides depending on where you cd to. If you don't use direnv, then I don't know what the appropriate environment should be.

mrnugget commented 7 months ago

@szlend agree with you! I think the proposed solution in this ticket -- using a language server if it's in $PATH -- is good and we should implement it, but when @as-cii and I talked about it, we said that it probably only makes sense on a language-by-language basis. For gopls and zls it makes sense, but for the other servers powered by node it becomes a bit more tricky.

szlend commented 7 months ago

For gopls and zls it makes sense, but for the other servers powered by node it becomes a bit more tricky.

Personally I would prefer if all language servers supported loading from PATH. Or at least have a configuration option to enable this if you think it's not a good default for zed. Though I imagine that's not something we can really enforce as language servers start moving outside the official repo.

paperdave commented 7 months ago

on top of supporting PATH, i think it would be nice if the exact path to the language server binary could be specified, and allow this configuration per project. this way, it can be made certain that the correct binary is loaded, especially in places where you want to work on the language server itself. trying to orchestrate PATH manually for these kinds of use cases is not fun.

domenkozar commented 7 months ago

Why this is important: Haskell needs LSP to be compiled against the same version of GHC that the tooling is built with.

mrnugget commented 7 months ago

I wrote up some ideas and proposed solutions in #7902 — if you want, can you (whoever wants!) take a look and leave your thoughts and poke holes in it, if possible?

domenkozar commented 2 months ago

See also #4977

JosephTLyons commented 1 month ago

This is now included in today's v0.148.0-pre release, and will go out to stable next week.

mrnugget commented 1 month ago

Just to clarify: what landed in the release is support for running vtsls from $PATH. Not all language servers.