From db86febc0cfa2516b516e4fac03e4bb94cabdb62 Mon Sep 17 00:00:00 2001 From: Ian Chamberlain Date: Sun, 30 Nov 2025 23:58:30 -0800 Subject: [PATCH] direnv: Allow disabling env integration entirely (#43764) Relates to #35759, but maybe doesn't entirely fix it? I think it will improve the situation, at least. Also provides a workaround for the issue described in https://github.com/zed-industries/zed/issues/40094#issuecomment-3559808526 for users of WSL + `nix-direnv`. Rationale: there are cases where automatic direnv integration is not always desirable, but Zed currently has no way of opting out of this integration besides `direnv revoke` (which is often not desirable). This PR provides such an opt-out for users who run into problems with the existing direnv integration methods. Some reasons why disabling might be useful: - Security concerns about auto-loading `.envrc` (arguably, `direnv revoke` should cover this most of the time) - As in #35759, for users who use different shells/envs for interactive/non-interactive cases and want to manually control the environment Zed uses - As in #40094, to workaround OS limits on environment variable / command-line parameter size Release Notes: - Added the ability to disable direnv integration entirely --- assets/settings/default.json | 2 ++ crates/project/src/environment.rs | 5 +++++ crates/settings/src/settings_content/project.rs | 2 ++ docs/src/configuring-zed.md | 3 ++- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index a222a16cb290eae905a69b492e9de8d3a1493592..d321c176a59d492b6d1b3b7a22dca0d31e5c6298 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1350,6 +1350,8 @@ // "load_direnv": "direct" // 2. Load direnv configuration through the shell hook, works for POSIX shells and fish. // "load_direnv": "shell_hook" + // 3. Don't load direnv configuration at all. + // "load_direnv": "disabled" "load_direnv": "direct", "edit_predictions": { // A list of globs representing files that edit predictions should be disabled for. diff --git a/crates/project/src/environment.rs b/crates/project/src/environment.rs index 32ed2f87668979802a44dcc233a1e87dc3c2e958..c4e807621ee27374b970b956551575ca4ae94f8b 100644 --- a/crates/project/src/environment.rs +++ b/crates/project/src/environment.rs @@ -314,6 +314,10 @@ async fn load_directory_shell_environment( load_direnv: DirenvSettings, tx: mpsc::UnboundedSender, ) -> anyhow::Result> { + if let DirenvSettings::Disabled = load_direnv { + return Ok(HashMap::default()); + } + let meta = smol::fs::metadata(&abs_path).await.with_context(|| { tx.unbounded_send(format!("Failed to open {}", abs_path.display())) .ok(); @@ -355,6 +359,7 @@ async fn load_directory_shell_environment( // even if direnv direct mode is enabled. let direnv_environment = match load_direnv { DirenvSettings::ShellHook => None, + DirenvSettings::Disabled => bail!("direnv integration is disabled"), // Note: direnv is not available on Windows, so we skip direnv processing // and just return the shell environment DirenvSettings::Direct if cfg!(target_os = "windows") => None, diff --git a/crates/settings/src/settings_content/project.rs b/crates/settings/src/settings_content/project.rs index 0076721228b3b8c6b8d5e6bfd85fc1d25f00c5e3..25a36580b007a8d41c9a90523298ca9f2b52b8d2 100644 --- a/crates/settings/src/settings_content/project.rs +++ b/crates/settings/src/settings_content/project.rs @@ -507,6 +507,8 @@ pub enum DirenvSettings { /// Load direnv configuration directly using `direnv export json` #[default] Direct, + /// Do not load direnv configuration + Disabled, } #[derive( diff --git a/docs/src/configuring-zed.md b/docs/src/configuring-zed.md index 2d866677650a0da141f27b3c78f7ad96f9581967..3b90120407fe56643e4b3f279d88443b9740e154 100644 --- a/docs/src/configuring-zed.md +++ b/docs/src/configuring-zed.md @@ -584,10 +584,11 @@ Note: Dirty files (files with unsaved changes) will not be automatically closed **Options** -There are two options to choose from: +There are three options to choose from: 1. `shell_hook`: Use the shell hook to load direnv. This relies on direnv to activate upon entering the directory. Supports POSIX shells and fish. 2. `direct`: Use `direnv export json` to load direnv. This will load direnv directly without relying on the shell hook and might cause some inconsistencies. This allows direnv to work with any shell. +3. `disabled`: No shell environment will be loaded automatically; direnv must be invoked manually (e.g. with `direnv exec`) to be used. ## Double Click In Multibuffer