From f17d2c92b6f8982d3be9d5858edb008efe1112f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Engin=20A=C3=A7=C4=B1kg=C3=B6z?= Date: Tue, 18 Nov 2025 15:37:48 +0300 Subject: [PATCH] terminal_view: Fix terminal opening in root directory when editing single file corktree (#42953) Fixes #42945 ## Problem When opening a single file via command line (e.g., `zed ~/Downloads/file.txt`), the terminal panel was opening in the root directory (/) instead of the file's directory. ## Root Cause The code only checked for active project directory, which returns None when a single file is opened. Additionally, file worktrees weren't handling parent directory lookup. ## Solution Added fallback logic to use the first project directory when there's no active entry, and made file worktrees return their parent directory instead of None. ## Testing - All existing tests pass - Added test coverage for file worktree scenarios - Manually tested with `zed ~/Downloads/file.txt` - terminal now opens in correct directory This improves the user experience for users who frequently open single files from the command line. ## Release Notes - Fixed terminal opening in root directory when editing single files from the command line --- crates/terminal_view/src/terminal_view.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index b9dabee7e82064ebe055893306241f995654b82b..66e6c605f9b560dc36db3dde16e84c2ee8c0c5b5 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1556,7 +1556,8 @@ pub(crate) fn default_working_directory(workspace: &Workspace, cx: &App) -> Opti .read(cx) .active_project_directory(cx) .as_deref() - .map(Path::to_path_buf), + .map(Path::to_path_buf) + .or_else(|| first_project_directory(workspace, cx)), WorkingDirectory::FirstProjectDirectory => first_project_directory(workspace, cx), WorkingDirectory::AlwaysHome => None, WorkingDirectory::Always { directory } => { @@ -1570,10 +1571,13 @@ pub(crate) fn default_working_directory(workspace: &Workspace, cx: &App) -> Opti ///Gets the first project's home directory, or the home directory fn first_project_directory(workspace: &Workspace, cx: &App) -> Option { let worktree = workspace.worktrees(cx).next()?.read(cx); - if !worktree.root_entry()?.is_dir() { - return None; + let worktree_path = worktree.abs_path(); + if worktree.root_entry()?.is_dir() { + Some(worktree_path.to_path_buf()) + } else { + // If worktree is a file, return its parent directory + worktree_path.parent().map(|p| p.to_path_buf()) } - Some(worktree.abs_path().to_path_buf()) } #[cfg(test)] @@ -1606,7 +1610,7 @@ mod tests { }); } - // No active entry, but a worktree, worktree is a file -> home_dir() + // No active entry, but a worktree, worktree is a file -> parent directory #[gpui::test] async fn no_active_entry_worktree_is_file(cx: &mut TestAppContext) { let (project, workspace) = init_test(cx).await; @@ -1621,9 +1625,9 @@ mod tests { assert!(workspace.worktrees(cx).next().is_some()); let res = default_working_directory(workspace, cx); - assert_eq!(res, None); + assert_eq!(res, Some(Path::new("/").to_path_buf())); let res = first_project_directory(workspace, cx); - assert_eq!(res, None); + assert_eq!(res, Some(Path::new("/").to_path_buf())); }); }