-
Notifications
You must be signed in to change notification settings - Fork 2.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. |
This is a bit related to #5347 in the sense that you want to:
So far, all the IDEs I have seen do this wrong as they try to resolve and execute binaries from the IDE's context. Sometimes, they allow updating the IDE's ENV, and then it breaks down when working on two different projects at the same time. Creating this architecture is also helpful for other things, like moving to a future where project code is sandboxed correctly and doesn't have arbitrary access to all of $HOME. |
This fixes #12125 and what's described in here: - #4977 (comment) Before the changes in this PR, when running tasks, they inherited the Zed process environment, but that might not be the process environment that you'd get if you `cd` into a project directory. We already ran into that problem with language servers and we fixed it by loading the shell environment in the context of a projects root directory and then passing that to the language servers when starting them (or when looking for their binaries). What the change here does is to add the behavior for tasks too: we use the project-environment as the base environment with which to spawn tasks. Everything else still works the same, except that the base env is different.
This fixes #12125 and what's described in here: - #4977 (comment) Before the changes in this PR, when running tasks, they inherited the Zed process environment, but that might not be the process environment that you'd get if you `cd` into a project directory. We already ran into that problem with language servers and we fixed it by loading the shell environment in the context of a projects root directory and then passing that to the language servers when starting them (or when looking for their binaries). What the change here does is to add the behavior for tasks too: we use the project-environment as the base environment with which to spawn tasks. Everything else still works the same, except that the base env is different.
This fixes #12125 and addresses what's described in here: - #4977 (comment) Before the changes in this PR, when running tasks, they inherited the Zed process environment, but that might not be the process environment that you'd get if you `cd` into a project directory. We already ran into that problem with language servers and we fixed it by loading the shell environment in the context of a projects root directory and then passing that to the language servers when starting them (or when looking for their binaries). What the change here does is to add the behavior for tasks too: we use the project-environment as the base environment with which to spawn tasks. Everything else still works the same, except that the base env is different. Release Notes: - Improved the environment-variable detection when running tasks so that tasks can now access environment variables as if the task had been spawned in a terminal that `cd`ed into a project directory. That means environment variables set by `direnv`/`asdf`/`mise` and other tools are now picked up. ([#12125](#12125)). Demo: https://github.com/user-attachments/assets/8bfcc98f-0f9b-4439-b0d9-298aef1a3efe
This fixes zed-industries#12125 and addresses what's described in here: - zed-industries#4977 (comment) Before the changes in this PR, when running tasks, they inherited the Zed process environment, but that might not be the process environment that you'd get if you `cd` into a project directory. We already ran into that problem with language servers and we fixed it by loading the shell environment in the context of a projects root directory and then passing that to the language servers when starting them (or when looking for their binaries). What the change here does is to add the behavior for tasks too: we use the project-environment as the base environment with which to spawn tasks. Everything else still works the same, except that the base env is different. Release Notes: - Improved the environment-variable detection when running tasks so that tasks can now access environment variables as if the task had been spawned in a terminal that `cd`ed into a project directory. That means environment variables set by `direnv`/`asdf`/`mise` and other tools are now picked up. ([zed-industries#12125](zed-industries#12125)). Demo: https://github.com/user-attachments/assets/8bfcc98f-0f9b-4439-b0d9-298aef1a3efe
It looks like that direnv is now officially supported: https://github.com/zed-industries/zed/blob/main/docs/src/configuring-zed.md#direnv-integration |
Does it work with multiple direnv environments loaded at the same time? |
Direnv does NOT just work. It mostly doesn't seem to work at all, and if you read the fine print on the docs, it says:
I need it to find other things, like elixir in a path modified by direnv. It doesn't have the path as direnv sets it :( |
This is still true after 0360cda ? From the changelog on
|
I'm still on Zed 0.146.5, so looks like I need to wait till 147.2 hits? That's super exciting! |
Hmm, I installed zed preview, which is 147.2, and when I run this task:
it still shows the path without direnv's changes to it. I'm using nix, if it matters. :( |
How do you use Here's what I use with Zed Preview 0.147.2:
So, how exactly is your |
Thanks for taking the time to try to help me out. I think I have things working now, but I did find a couple bugs along the way. Here's a play project that someone can hopefully repro them with: It has this .envrc file:
And this .zed/tasks.json file:
When I open zed and run the show path task, the behavior I see is:
I'm on an M2 Max mac running Sonoma 14.6. |
Okay, let me first answer (2), since (1) is tricky and I need to dive into it.
That's because when spawning tasks, we spawn an interactive shell, which then sources your Here, all the things that come before That's reproducible when running the same command that Zed runs when executing the task: I'm not sure how to fix it yet. Workaround could be to change your shell config to detect when any of the |
Okay, this is a bit of a nasty one. I think I know what's going on now:
So, what do we do about it? I think there are a bunch of options and I need to think through the trade-offs of them, but here's what we/you could do, off the top of my head:
We really should do (1) and the subtask, but we're very busy now with an upcoming launch, so I'm probably not going to get to that in the next couple of weeks. |
Using 0.147.2, with direnv activated and I wish there way a way to disable auto-downloading all together and using only $PATH. |
@domenkozar did you turn the PATH-lookup on for rust-analyzer? It's not the default for rust-analyzer since r-a behaves different than other language servers somehow. {
"lsp": {
"rust-analyzer": {
"binary": {"path_lookup": true}
}
}
} (Edit: documented as part of our docs party today: 1683186) |
Same result:
Note that I'd expect |
It works for me:
Then I open
Can you show your |
{
"assistant": {
"version": "2",
"default_open_ai_model": null,
"default_model": {
"provider": "anthropic",
"model": "claude-3-5-sonnet-20240620"
}
},
"lsp": {
"rust-analyzer": {
"binary": {"path_lookup": true}
}
},
"vim_mode": true,
"base_keymap": "VSCode",
"theme": "One Dark",
"ui_font_size": 16,
"buffer_font_size": 16
} |
Nothing wrong there. With your settings it also works for me:
|
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: