terminal: Skip SHLVL when loading login shell environment (#46273)
rari404
created
Fixes #33958
## Problem
PR #44835 attempted to fix SHLVL starting at 2 by removing it from the
`env` HashMap passed to alacritty. However, that HashMap is only an
**overlay** ā alacritty uses the parent process environment as a base
and applies the overlay on top. Since alacritty never calls
`env_remove("SHLVL")`, the terminal shell still inherits `SHLVL` from
Zed's process environment.
## Root Cause
The real issue is in `load_login_shell_environment()`:
1. `shell_env::capture()` spawns a login shell to capture environment
variables
2. That login shell increments `SHLVL` (from 0ā1 or nān+1)
3. The captured env (including the incremented `SHLVL`) is written to
Zed's **process environment** via `env::set_var`
4. When you open a terminal, the shell inherits Zed's `SHLVL` and
increments it again ā starts at 2
5. On reload, `shell_env::capture()` runs again with the
already-elevated `SHLVL`, incrementing it further ā +2 per reload
## Fix
Skip `SHLVL` when setting Zed's process environment in
`load_login_shell_environment()`. This prevents the login-shell capture
from polluting Zed's env, so terminals start fresh with the correct
`SHLVL`.
@@ -365,6 +365,13 @@ pub async fn load_login_shell_environment() -> Result<()> {
.await
.with_context(|| format!("capturing environment with {:?}", get_system_shell()))?
{
+ // Skip SHLVL to prevent it from polluting Zed's process environment.
+ // The login shell used for env capture increments SHLVL, and if we propagate it,
+ // terminals spawned by Zed will inherit it and increment again, causing SHLVL
+ // to start at 2 instead of 1 (and increase by 2 on each reload).
+ if name == "SHLVL" {
+ continue;
+ }
unsafe { env::set_var(&name, &value) };
}