-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Use direnv
environment
#4977
Comments
A few issues that almost every editor suffers from when implementing
Just something worth considering when designing the extension API and implementing this feature. |
Yep, the extension API must have support for this usecase to properly implement direnv integration. This is the reason why https://github.com/misuzu/direnv-subl is flawed - ST just doesn't have the necessary API. The direnv integration that just works would be The Feature that can ease the pain of setting up any project for many people. |
Another useful feature that I think a Also initializing direnv can take some time. For example if you use direnv to load a nix shell, it might actually start downloading packages or even compiling. So it might make sense to show some sort of indicator that direnv is still evaluating something. And a way to cancel it. |
This is definitely keeping us from using zed on our project. We use direnv + nix, and we can't use tasks w/o better support. With VSCode, it's quite easy to use direnv, you just have to launch the editor from a directory that direnv has already run with |
it seems the termina doesn't maintain its env between runs, because if it did, we could work around this by sourcing a script like this:
|
I found a workaround that is semi-usable: running zed with If I try to open a second project with a different env, with |
When you open a project, we spawn a login shell in that project's root dir, get the It sounds like you have direnv/nix setup so that would work, is the problem now that it doesn't work with tasks? |
Thanks @mersinvald , but your workaround doesn't work for me, specifically with tasks, which is my problem. I need to be able to run the test under my cursor from my IDE. And when I open up a task to do that, it doesn't have any of the env that direnv setup :( |
This definitely does not work well in vscode, except for the initial window. The direnv vscode extension fixes this and makes it somewhat usable, but it still causes cross-project env pollution from the initial vscode window. I think how Zed does it is a step in the right direction, though it's difficult to diagnose issues when something goes wrong. It might be a good idea to document the env loading behavior and some steps to help diagnose issues (e.g. how do I inspect the window's env, what login shell Zed used to initialize the env, etc.) |
Right now that's all printed in the logs ( But yes, documentation is a good idea.
It uses It doesn't spawn This is what we do on start, in Lines 309 to 312 in 05b6581
And this is what we do for the language servers, per project: zed/crates/project/src/project.rs Lines 11636 to 11665 in 05b6581
|
It looks like that {
"lsp": { "rust-analyzer": { "binary": { "path_lookup": true } } }
} But it's still tries to download and run its own binary anyways (and failing because I'm on NixOS). |
Yes, because that commit you linked to hasn't been in any release yet. |
@mrnugget it doesn't work for me without the foreground hack. If I just open the project, the env from .envrc wouldn't be loaded for anything except the integrated shell.
Is there a way to modify what runs in this shell before editor initialization? |
what doesn't work? Only certain language servers make use of this environment right now. |
I would like the editor to respect the directory env regardless of what specific plugin needs it. In my case, the issue is with Log without the foreground hack (neither rustup or cargo are installed in the system, only in a project flake)
|
That should then be possible with the upcoming Preview release and when setting |
Alright, I want to show you where it's not working for me. You can see that when I go into my project directory, direnv runs and we are finding elixir from nix. But after launching zed, even with foreground, within a task, it finds elixir from asdf :(. Which means all my tests fail and I can't do things like For VSCode, it works because the first time I run a task, it opens and fails, then I can manually type |
Yeah, that's not supported yet. |
Zed + direnv + Nix + Rust (rust-analyzer) has been consistently working well for me. Environment: macOS, with nothing (but Nix) globally installed. The project in question: https://github.com/juspay/omnix My Zed config: {
"base_keymap": "VSCode",
"load_direnv": "shell_hook",
"lsp": { "rust-analyzer": { "binary": { "path_lookup": true } } },
"vim_mode": true,
}
|
Incidentally, to get nixd (Nix language server) working, I had to add the following to Zed config: {
"lsp": {
"rust-analyzer": { "binary": { "path_lookup": true } },
"nix": { "binary": { "path_lookup": true } }
},
} Perhaps |
One thing I noticed is this configuration works only if you put it in your user config ( |
Yep! If the binary exists in the path, please just use it. |
Not strictly a bug, but: we only allow overwriting certain settings in project-specific settings. But yeah, agree, this should probably be one. |
I agree, but last time I did that, lots of |
@srid Which version of Zed are you using? I am using Zed 0.149.3 on Mac OS 14.6.1. My projects use Nix with direnv. Zed is able to find LSP servers like It was sufficient to set |
@rome-user I definitely have to enable |
A good step forward would be to have a global |
In case it helps anyone else, this was my solution/workaround. tl;dr What was tripping me up is that it was saying My Problem when using nix + direnv + rust-analyzer (essentially just a restatement of earlier messages here)In various projects that work as is in VS code with no RA-related settings, I'm having trouble getting RA to run. I've added
to
This is the same behavior as when I follow the steps @mrnugget mentioned above
My Solution/WorkaroundBasically I eventually just followed the error I'd overlooked in the logs which states
So I ran
and then ran
Works great now! |
in nixos. when I launch zed inside an manually launched development shell. |
@DrewBurkhart thanks so much for that debugging! That's going to help. |
This changes the Zed CLI `zed` to pass along the environment to the Zed project that it opens (if it opens a new one). In projects, this CLI environment will now take precedence over any environment that's acquired by running a login shell in a projects folder. The result is that `zed my/folder` now always behaves as if one would run `zed --foreground` without any previous Zed version running. Closes #7894 Closes #16293 Related issues: - It fixes the issue described in here: #4977 (comment) Release Notes: - Improved the Zed CLI `zed` to pass along the environment as it was on the CLI to the opened Zed project. That environment is then used when opening new terminals, spawning tasks, or language servers. Specifically: - If Zed was started via `zed my-folder`, a terminal spawned with `workspace: new terminal` will inherit these environment variables that existed on the CLI - Specific language servers that allow looking up the language server binary in the environments `$PATH` (such as `gopls`, `zls`, `rust-analyzer` if configured, ...) will look up the language server binary in the CLI environment too and use that environment when starting the process. - Language servers that are _not_ found in the CLI environment (or configured to not be found in there), will be spawned with the CLI environment in case that's set. That means users can do something like `RA_LOG=info zed .` and it will be picked up the rust-analyzer that was spawned. Demo/explanation: https://github.com/user-attachments/assets/455905cc-8b7c-4fc4-b98a-7e027d97cdfa
Currently, some LSPs call Ideally, the extension API would provide Once that lands I'll write documentation for devenv. |
I'm in the process of turning |
I no longer experience this issue with the latest version ( Now it loads the expected, project-specific, binary (here
Unfortunately, it seems to work correctly only when reloading a project. If Zed auto-loads a project on startup, it fails to detect the binaries, but if I toggle between projects, it detects the binaries both in the secondary project and the initial one. In addition to that, this correlates with the shell (fish) and/or terminal pane not working correctly: deleting characters (or whole words) deletes them only logically, but not physically (they are still displayed); my configured shell prompt colors are also missing. One peculiar thing is how the terminal tab handle differs in these two scenarios. Notice the Zed-inserted horizontal divider after the inserted fish cwd prompt:
|
Is it possible that you start Zed from the CLI there? In that case, that environment takes precedence over everything else we load. |
Yes. The result of doing that is the same as opening a project from an existing instance. Here are the scenarios, possibly non-exhaustive, where the LSP binaries are un/detected:
After comparing Zed logs and shell environments across all these scenarios, I've concluded that, in the Undetected cases, the main Zed process simply doesn't load the direnv environment. However, in both Undetected and Detected cases, the Zed terminal shell is spawned with the correct environment. Toggling between Relevant log lines with the actual paths elided:
The paths in question, present in all the Detected cases above, yet missing in all the Undetected ones, are as follows:
Looking at the code, I'm not sure why a login shell must be invoked just to grab the environment. To my mind, it is the user's responsibility to set their session variables as they see fit. In other words, the environment available to Zed at invocation time, regardless of how it's invoked, that should be the initial environment. The environment generated by [1] For the sake of completeness (and correctness), this would likely have to be bidirectional (i.e., terminal shell -> Zed should work as well), in the event that direnv picks up changes to |
My understanding is this is necessary to get a fresh base environment, otherwise the environment from the first window pollutes the environment of subsequent windows you open, since they all share the same base environment (they're not fresh processes but fork of the original process).
This has caused me countless problems in vscode. I would open project A in vscode, and it would set some env var like Imo this is one of the things zed does right, even if it doesn't yet handle every edge case. Ideally each zed window was a fresh process, but I'm not sure how realistic that is given the IPC needs. |
Is there a reason this issue is still open? Seems like support is working fine now for the most part, other issues should probably be bug reports since the core functionality should be all there? I got confused thinking Zed didn't support direnv at all because this feature request was open. |
Yeah, agree. Let's close this and open separate issues with MREs in them. |
Check for existing issues
Describe the feature
Zed should support direnv, to enable using a different environment (espeacially
$PATH
) for different projects. In combination with #4978 this would enable e.g. using different versions of language servers and tooling, or tooling just installed for the project instead of system-wide using Nix.If applicable, add mockups / screenshots to help present your vision of the feature
Inspiration from other editors:
The text was updated successfully, but these errors were encountered: