From 9961d18247db5d003d7641f13fb2cc11b88708d5 Mon Sep 17 00:00:00 2001 From: "zed-zippy[bot]" <234243425+zed-zippy[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 07:17:53 +0000 Subject: [PATCH] terminal_view: Fix terminal opening in / when no project is open (#46582) (cherry-pick to preview) (#46682) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-pick of #46582 to preview ---- Closes #46574 The `default_working_directory()` function in `crates/terminal_view/src/terminal_view.rs:1585` returned `None` when no project directory was available. The code comment (now removed) incorrectly claimed "None implies `~` on whichever machine we end up on". However, when `None` is passed to `alacritty_terminal`, it uses the process CWD, not the home directory. On macOS when Zed is launched from a .`app` bundle, the CWD is `/`. Added a fallback at the end of` default_working_directory()` that explicitly returns the home directory when no project directory is found: `directory.or_else(dirs::home_dir)` This ensures: 1. `CurrentProjectDirectory` with no project open → home directory 2. `FirstProjectDirectory `with no project open → home directory 3. `AlwaysHome `→ home directory (explicitly, not relying on shell behavior) 4. Always `{ directory }` with invalid directory → home directory Release Notes: - Fixed terminal opening in `/` instead of home directory when no project is open. Co-authored-by: Max Malkin <60683392+maxmalkin@users.noreply.github.com> --- crates/terminal_view/src/terminal_view.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index e7e60ff4b31dfbdd16b7de8841285d81fc311fc5..2604de55a7a62e4ec2965b882ef8466f9362f09c 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1580,10 +1580,10 @@ impl SearchableItem for TerminalView { } } -///Gets the working directory for the given workspace, respecting the user's settings. -/// None implies "~" on whichever machine we end up on. +/// Gets the working directory for the given workspace, respecting the user's settings. +/// Falls back to home directory when no project directory is available. pub(crate) fn default_working_directory(workspace: &Workspace, cx: &App) -> Option { - match &TerminalSettings::get_global(cx).working_directory { + let directory = match &TerminalSettings::get_global(cx).working_directory { WorkingDirectory::CurrentProjectDirectory => workspace .project() .read(cx) @@ -1593,13 +1593,12 @@ pub(crate) fn default_working_directory(workspace: &Workspace, cx: &App) -> Opti .or_else(|| first_project_directory(workspace, cx)), WorkingDirectory::FirstProjectDirectory => first_project_directory(workspace, cx), WorkingDirectory::AlwaysHome => None, - WorkingDirectory::Always { directory } => { - shellexpand::full(&directory) //TODO handle this better - .ok() - .map(|dir| Path::new(&dir.to_string()).to_path_buf()) - .filter(|dir| dir.is_dir()) - } - } + WorkingDirectory::Always { directory } => shellexpand::full(directory) + .ok() + .map(|dir| Path::new(&dir.to_string()).to_path_buf()) + .filter(|dir| dir.is_dir()), + }; + directory.or_else(dirs::home_dir) } ///Gets the first project's home directory, or the home directory fn first_project_directory(workspace: &Workspace, cx: &App) -> Option { @@ -1637,7 +1636,7 @@ mod tests { assert!(workspace.worktrees(cx).next().is_none()); let res = default_working_directory(workspace, cx); - assert_eq!(res, None); + assert_eq!(res, dirs::home_dir()); let res = first_project_directory(workspace, cx); assert_eq!(res, None); });