## Summary Creating a new file via the file picker incorrectly used the focused file's directory as the target even when that file did not belong to any open worktree (e.g., Zed opened to a single file, settings.json focused without a worktree, or an external file focused). This PR changes the selection logic so the picker only uses the focused file's worktree if that file actually belongs to one of the visible project worktrees; otherwise, it falls back to the existing project heuristic (query-root match or project default), which prevents misdirected file creation. This addresses [zed-industries/zed#41940](https://github.com/zed-industries/zed/issues/41940). --- ## Problem ### Scenarios that errored or created in the wrong place: 1. **Zed opened to a single file from the CLI** (no worktree) - Create New was offered and then failed or targeted a non-project directory 2. **No worktree open with settings.json focused** - Same failure mode as above 3. **A worktree is open but settings.json is focused** - Create New used settings.json's directory 4. **A worktree is open but an external (non-worktree) file is focused** - Create New used the external file's directory ### Root Cause `set_search_matches` unconditionally overwrote `expect_worktree` using the `currently_opened_path` worktree_id, even if the focused file was not part of any visible worktree. --- ## Fix ### Query-derived worktree remains primary: - Try to match the query path against the roots of visible worktrees - If it matches, use that worktree and strip the root prefix from the query to get the relative path ### Only use the focused file as a secondary signal if it is relevant: - Check whether the focused file's `worktree_id` exists within visible worktrees - Only then override `expect_worktree` If no worktree is determined (e.g., no worktrees are open), Create New is not offered. --- ## Implementation Details - **Iterate over `&available_worktree`** when scanning roots and clone the matched entity to avoid moving out of the iterator - **Validate focused file worktree membership:** - Compute `focused_file_in_available_worktree` by scanning visible worktrees for a matching id - Override `expect_worktree` only if that check passes - **Preserve existing guard rails for Create New:** - Only push `Match::CreateNew` when a concrete `expect_worktree` is present and the query doesn't end with a trailing separator --- ## Key Code Changes ### Before Always overwrote `expect_worktree` with the focused file's `worktree_id`, even for external or non-project files. ### After Only override `expect_worktree` when the focused file belongs to a visible worktree. Otherwise, keep the query-derived or default project worktree. --- ## User-Facing Behavior ### No Worktree Open *Example: Zed launched with a single file or only settings.json visible* - The file picker will **not** offer "Create New" ### Worktree Open + Non-Project File Focused *Example: A non-project file or settings.json is in focus* - "Create New" is offered - New file is created within the project worktree (based on root match or project default) - New file is **never** created beside the external file ### Multiple Worktrees Open + Query Rooted to One *Example: Query specifies a particular worktree root* - The worktree is selected by root-name match - Project default selection applies if no match is found --- ## Tests ### Added: `test_create_file_focused_file_not_belong_to_available_worktrees` 1. Set up two worktrees A and B; open an external file that belongs to neither 2. Use the file picker to create "new-file.txt" 3. Assert the new file opens in an editor whose `ProjectPath.worktree_id` equals either A or B, and the relative path is "new-file.txt" Existing tests for Create New, absolute/relative matching, and multi-worktree behavior continue to pass. --- ## Reproduction Steps (Pre-Fix) 1. Launch Zed with a single file: ```bash zed /tmp/foo.txt ``` Or open settings.json with no project 2. Open the file finder and type a new filename, then press Enter 3. Observe Create New trying to use the focused file's directory or failing unexpectedly --- ## Expected vs Actual ### Expected: - No Create New when there is no project worktree - When a project exists, Create New targets the appropriate worktree, not the focused external file's directory ### Actual (pre-fix): - Create New used the focused file's directory, even if it was external or unrelated to the project --- ## Migration and Compatibility - No user configuration changes required - Behavior now aligns with user expectation: Create New is only offered when a project worktree is available and it always targets a project worktree --- ## Reference **Fixes:** [zed-industries/zed#41940](https://github.com/zed-industries/zed/issues/41940) Fixes #41940 --- ## Appendix: Code Snippets ### Guard before overriding with focused file: ```rust let focused_file_in_available_worktree = available_worktree.iter().any(|wt| wt.read(cx).id() == worktree_id); if focused_file_in_available_worktree { expect_worktree = project.worktree_for_id(worktree_id, cx); } ``` ### Root-based worktree selection with non-moving iteration: ```rust for worktree in &available_worktree { if query_path.strip_prefix(worktree.read(cx).root_name()).is_ok() { expect_worktree = Some(worktree.clone()); … } } ``` --- This PR includes a targeted test ensuring that when the focused file is outside all worktrees, Create New still creates within the project worktree(s), preventing regressions. --- ## Release Notes - Fixed "Create New" in the file picker targeting the wrong directory when a non-project file was focused. --- --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|---|---|---|
| .cargo | ||
| .cloudflare | ||
| .config | ||
| .factory/prompts/docs-automation | ||
| .github | ||
| .zed | ||
| assets | ||
| ci | ||
| crates | ||
| docs | ||
| extensions | ||
| legal | ||
| nix | ||
| script | ||
| tooling | ||
| .git-blame-ignore-revs | ||
| .gitattributes | ||
| .gitignore | ||
| .mailmap | ||
| .prettierrc | ||
| .rules | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| clippy.toml | ||
| CODE_OF_CONDUCT.md | ||
| compose.yml | ||
| CONTRIBUTING.md | ||
| debug.plist | ||
| default.nix | ||
| Dockerfile-collab | ||
| Dockerfile-collab.dockerignore | ||
| Dockerfile-cross.dockerignore | ||
| Dockerfile-distros | ||
| Dockerfile-distros.dockerignore | ||
| flake.lock | ||
| flake.nix | ||
| GEMINI.md | ||
| LICENSE-AGPL | ||
| LICENSE-APACHE | ||
| LICENSE-GPL | ||
| livekit.yaml | ||
| lychee.toml | ||
| Procfile | ||
| Procfile.all | ||
| Procfile.web | ||
| README.md | ||
| renovate.json | ||
| REVIEWERS.conl | ||
| rust-toolchain.toml | ||
| rustfmt.toml | ||
| shell.nix | ||
| typos.toml | ||
Zed
Welcome to Zed, a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
Installation
On macOS, Linux, and Windows you can download Zed directly or install Zed via your local package manager (macOS/Linux/Windows).
Other platforms are not yet available:
- Web (tracking issue)
Developing Zed
Contributing
See CONTRIBUTING.md for ways you can contribute to Zed.
Also... we're hiring! Check out our jobs page for open roles.
Licensing
License information for third party dependencies must be correctly provided for CI to pass.
We use cargo-about to automatically comply with open source licenses. If CI is failing, check the following:
- Is it showing a
no license specifiederror for a crate you've created? If so, addpublish = falseunder[package]in your crate's Cargo.toml. - Is the error
failed to satisfy license requirementsfor a dependency? If so, first determine what license the project has and whether this system is sufficient to comply with this license's requirements. If you're unsure, ask a lawyer. Once you've verified that this system is acceptable add the license's SPDX identifier to theacceptedarray inscript/licenses/zed-licenses.toml. - Is
cargo-aboutunable to find the license for a dependency? If so, add a clarification field at the end ofscript/licenses/zed-licenses.toml, as specified in the cargo-about book.
Sponsorship
Zed is developed by Zed Industries, Inc., a for-profit company.
If you’d like to financially support the project, you can do so via GitHub Sponsors. Sponsorships go directly to Zed Industries and are used as general company revenue. There are no perks or entitlements associated with sponsorship.