file_finder: Fix path duplication when opening non-project files with a filter - #54944
Merged
yara-blue merged 3 commits intoJun 2, 2026
Conversation
saberoueslati
force-pushed
the
file_finder/fix-single-file-worktree-path-duplication
branch
from
April 28, 2026 11:24
0eb6912 to
79943a7
Compare
Contributor
Author
|
@ChristopherBiscardi can you run the CI/CD pipeline for this PR ? Thank you |
14 tasks
Contributor
|
Hi @saberoueslati sorry it took so long to get to this, now it unfortunately got a merge conflict. Could you adress that? Feel free to ping me when that is done! |
saberoueslati
force-pushed
the
file_finder/fix-single-file-worktree-path-duplication
branch
from
June 1, 2026 22:05
a16893a to
8115d22
Compare
Contributor
Author
|
@yara-blue thank you, conflict is resolved now |
yara-blue
approved these changes
Jun 2, 2026
Contributor
|
Thank you! looks great :) |
dandv
pushed a commit
to dandv/zed
that referenced
this pull request
Jun 3, 2026
… a filter (zed-industries#54944) ## Context When a file is opened outside any project, Zed creates a single-file worktree for it where the file's relative path is `""` (the worktree root IS the file). Typing to filter in the file picker (Ctrl-P) caused a crash: `Error: opening project path "/home/user/foo.txt/foo.txt"`. Two bugs combined to produce this: 1. **History lookup mismatch** : `fuzzy_nucleo` detects `root_is_file = true` for single-file worktrees and moves the worktree root name into `path_match.path` (so `"" → "foo.txt"`). `matching_history_items` stored the entry under key `""`but looked it up by `"foo.txt"` → miss → item dropped from history matches. 2. **Search confirm duplication** : because the history match was dropped, the file appeared as `Match::Search` with `path_match.path = "foo.txt"`. Confirming the constructed `ProjectPath { path: "foo.txt" }` inside a worktree rooted at `/home/user/foo.txt` → resolved to `/home/user/foo.txt/foo.txt`. Fix 1 adds a fallback empty-path lookup in `matching_history_items` so single-file worktree entries are found correctly and deduplication suppresses the search duplicate. Fix 2 is defense-in-depth: if a single-file worktree file ever reaches the `Match::Search` confirm handler, it detects `is_single_file()` and uses an empty path instead. **Edit :** After further work, two additional edge cases were fixed: - `Match::Search` split-open handling now uses the same single-file worktree path normalization as normal confirm. This prevents split-opening a single-file worktree search result from resolving `notes.txt` inside `/path/to/notes.txt` as `/path/to/notes.txt/notes.txt`. - History matching now still includes root names for single-file worktrees when `project_panel.hide_root = true`. Normal folder worktree roots remain hidden in this mode, but single-file worktrees need their root name included because the root name is the filename users type into the picker. Additional test coverage: - Added `test_non_project_file_matches_history_with_hidden_root` for the `hide_root=true` history matching edge case. - Added `test_single_file_search_result_split_open` for split-opening a single-file worktree search result. Closes zed-industries#54934 Manual test after fix below : [Screencast from 2026-04-26 23-58-00.webm](https://github.com/user-attachments/assets/3de564d8-cc94-4624-98e3-54dd124bfa2f) ## How to Review - `crates/file_finder/src/file_finder.rs` : Two targeted changes: - `matching_history_items` (~line 757): added `.or_else` fallback that retries the candidates lookup with an empty path when the first lookup misses, covering the `root_is_file` key mismatch for single-file worktrees. - `Match::Search` confirm handler (~line 1640): checks `wt.read(cx).is_single_file()` and substitutes `RelPath::empty()` for `path_match.path` to prevent duplication. - `crates/file_finder/src/file_finder_tests.rs` — Two test changes: - New test `test_non_project_file_open_with_filter`: opens a file outside the project, filters for it by name, confirms, and asserts the correct path is opened. - Updated `test_search_results_refreshed_on_standalone_file_creation`: the fix correctly promotes single-file worktree files to `Match::History`, which activates `skip_focus_for_active_in_search` when the file is currently open. The test now asserts the match type directly and closes the picker with `menu::Cancel` instead of confirming. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed file picker failing to open non-project files when a filter is typed
TomPlanche
pushed a commit
to TomPlanche/zed
that referenced
this pull request
Jun 8, 2026
… a filter (zed-industries#54944) ## Context When a file is opened outside any project, Zed creates a single-file worktree for it where the file's relative path is `""` (the worktree root IS the file). Typing to filter in the file picker (Ctrl-P) caused a crash: `Error: opening project path "/home/user/foo.txt/foo.txt"`. Two bugs combined to produce this: 1. **History lookup mismatch** : `fuzzy_nucleo` detects `root_is_file = true` for single-file worktrees and moves the worktree root name into `path_match.path` (so `"" → "foo.txt"`). `matching_history_items` stored the entry under key `""`but looked it up by `"foo.txt"` → miss → item dropped from history matches. 2. **Search confirm duplication** : because the history match was dropped, the file appeared as `Match::Search` with `path_match.path = "foo.txt"`. Confirming the constructed `ProjectPath { path: "foo.txt" }` inside a worktree rooted at `/home/user/foo.txt` → resolved to `/home/user/foo.txt/foo.txt`. Fix 1 adds a fallback empty-path lookup in `matching_history_items` so single-file worktree entries are found correctly and deduplication suppresses the search duplicate. Fix 2 is defense-in-depth: if a single-file worktree file ever reaches the `Match::Search` confirm handler, it detects `is_single_file()` and uses an empty path instead. **Edit :** After further work, two additional edge cases were fixed: - `Match::Search` split-open handling now uses the same single-file worktree path normalization as normal confirm. This prevents split-opening a single-file worktree search result from resolving `notes.txt` inside `/path/to/notes.txt` as `/path/to/notes.txt/notes.txt`. - History matching now still includes root names for single-file worktrees when `project_panel.hide_root = true`. Normal folder worktree roots remain hidden in this mode, but single-file worktrees need their root name included because the root name is the filename users type into the picker. Additional test coverage: - Added `test_non_project_file_matches_history_with_hidden_root` for the `hide_root=true` history matching edge case. - Added `test_single_file_search_result_split_open` for split-opening a single-file worktree search result. Closes zed-industries#54934 Manual test after fix below : [Screencast from 2026-04-26 23-58-00.webm](https://github.com/user-attachments/assets/3de564d8-cc94-4624-98e3-54dd124bfa2f) ## How to Review - `crates/file_finder/src/file_finder.rs` : Two targeted changes: - `matching_history_items` (~line 757): added `.or_else` fallback that retries the candidates lookup with an empty path when the first lookup misses, covering the `root_is_file` key mismatch for single-file worktrees. - `Match::Search` confirm handler (~line 1640): checks `wt.read(cx).is_single_file()` and substitutes `RelPath::empty()` for `path_match.path` to prevent duplication. - `crates/file_finder/src/file_finder_tests.rs` — Two test changes: - New test `test_non_project_file_open_with_filter`: opens a file outside the project, filters for it by name, confirms, and asserts the correct path is opened. - Updated `test_search_results_refreshed_on_standalone_file_creation`: the fix correctly promotes single-file worktree files to `Match::History`, which activates `skip_focus_for_active_in_search` when the file is currently open. The test now asserts the match type directly and closes the picker with `menu::Cancel` instead of confirming. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed file picker failing to open non-project files when a filter is typed
This was referenced Jun 10, 2026
This was referenced Jun 18, 2026
Closed
This was referenced Jul 1, 2026
This was referenced Jul 10, 2026
jonx
pushed a commit
to jonx/zed-aros
that referenced
this pull request
Jul 17, 2026
… a filter (zed-industries#54944) ## Context When a file is opened outside any project, Zed creates a single-file worktree for it where the file's relative path is `""` (the worktree root IS the file). Typing to filter in the file picker (Ctrl-P) caused a crash: `Error: opening project path "/home/user/foo.txt/foo.txt"`. Two bugs combined to produce this: 1. **History lookup mismatch** : `fuzzy_nucleo` detects `root_is_file = true` for single-file worktrees and moves the worktree root name into `path_match.path` (so `"" → "foo.txt"`). `matching_history_items` stored the entry under key `""`but looked it up by `"foo.txt"` → miss → item dropped from history matches. 2. **Search confirm duplication** : because the history match was dropped, the file appeared as `Match::Search` with `path_match.path = "foo.txt"`. Confirming the constructed `ProjectPath { path: "foo.txt" }` inside a worktree rooted at `/home/user/foo.txt` → resolved to `/home/user/foo.txt/foo.txt`. Fix 1 adds a fallback empty-path lookup in `matching_history_items` so single-file worktree entries are found correctly and deduplication suppresses the search duplicate. Fix 2 is defense-in-depth: if a single-file worktree file ever reaches the `Match::Search` confirm handler, it detects `is_single_file()` and uses an empty path instead. **Edit :** After further work, two additional edge cases were fixed: - `Match::Search` split-open handling now uses the same single-file worktree path normalization as normal confirm. This prevents split-opening a single-file worktree search result from resolving `notes.txt` inside `/path/to/notes.txt` as `/path/to/notes.txt/notes.txt`. - History matching now still includes root names for single-file worktrees when `project_panel.hide_root = true`. Normal folder worktree roots remain hidden in this mode, but single-file worktrees need their root name included because the root name is the filename users type into the picker. Additional test coverage: - Added `test_non_project_file_matches_history_with_hidden_root` for the `hide_root=true` history matching edge case. - Added `test_single_file_search_result_split_open` for split-opening a single-file worktree search result. Closes zed-industries#54934 Manual test after fix below : [Screencast from 2026-04-26 23-58-00.webm](https://github.com/user-attachments/assets/3de564d8-cc94-4624-98e3-54dd124bfa2f) ## How to Review - `crates/file_finder/src/file_finder.rs` : Two targeted changes: - `matching_history_items` (~line 757): added `.or_else` fallback that retries the candidates lookup with an empty path when the first lookup misses, covering the `root_is_file` key mismatch for single-file worktrees. - `Match::Search` confirm handler (~line 1640): checks `wt.read(cx).is_single_file()` and substitutes `RelPath::empty()` for `path_match.path` to prevent duplication. - `crates/file_finder/src/file_finder_tests.rs` — Two test changes: - New test `test_non_project_file_open_with_filter`: opens a file outside the project, filters for it by name, confirms, and asserts the correct path is opened. - Updated `test_search_results_refreshed_on_standalone_file_creation`: the fix correctly promotes single-file worktree files to `Match::History`, which activates `skip_focus_for_active_in_search` when the file is currently open. The test now asserts the match type directly and closes the picker with `menu::Cancel` instead of confirming. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed file picker failing to open non-project files when a filter is typed
jolutz
pushed a commit
to jolutz/zed
that referenced
this pull request
Aug 8, 2026
… a filter (zed-industries#54944) ## Context When a file is opened outside any project, Zed creates a single-file worktree for it where the file's relative path is `""` (the worktree root IS the file). Typing to filter in the file picker (Ctrl-P) caused a crash: `Error: opening project path "/home/user/foo.txt/foo.txt"`. Two bugs combined to produce this: 1. **History lookup mismatch** : `fuzzy_nucleo` detects `root_is_file = true` for single-file worktrees and moves the worktree root name into `path_match.path` (so `"" → "foo.txt"`). `matching_history_items` stored the entry under key `""`but looked it up by `"foo.txt"` → miss → item dropped from history matches. 2. **Search confirm duplication** : because the history match was dropped, the file appeared as `Match::Search` with `path_match.path = "foo.txt"`. Confirming the constructed `ProjectPath { path: "foo.txt" }` inside a worktree rooted at `/home/user/foo.txt` → resolved to `/home/user/foo.txt/foo.txt`. Fix 1 adds a fallback empty-path lookup in `matching_history_items` so single-file worktree entries are found correctly and deduplication suppresses the search duplicate. Fix 2 is defense-in-depth: if a single-file worktree file ever reaches the `Match::Search` confirm handler, it detects `is_single_file()` and uses an empty path instead. **Edit :** After further work, two additional edge cases were fixed: - `Match::Search` split-open handling now uses the same single-file worktree path normalization as normal confirm. This prevents split-opening a single-file worktree search result from resolving `notes.txt` inside `/path/to/notes.txt` as `/path/to/notes.txt/notes.txt`. - History matching now still includes root names for single-file worktrees when `project_panel.hide_root = true`. Normal folder worktree roots remain hidden in this mode, but single-file worktrees need their root name included because the root name is the filename users type into the picker. Additional test coverage: - Added `test_non_project_file_matches_history_with_hidden_root` for the `hide_root=true` history matching edge case. - Added `test_single_file_search_result_split_open` for split-opening a single-file worktree search result. Closes zed-industries#54934 Manual test after fix below : [Screencast from 2026-04-26 23-58-00.webm](https://github.com/user-attachments/assets/3de564d8-cc94-4624-98e3-54dd124bfa2f) ## How to Review - `crates/file_finder/src/file_finder.rs` : Two targeted changes: - `matching_history_items` (~line 757): added `.or_else` fallback that retries the candidates lookup with an empty path when the first lookup misses, covering the `root_is_file` key mismatch for single-file worktrees. - `Match::Search` confirm handler (~line 1640): checks `wt.read(cx).is_single_file()` and substitutes `RelPath::empty()` for `path_match.path` to prevent duplication. - `crates/file_finder/src/file_finder_tests.rs` — Two test changes: - New test `test_non_project_file_open_with_filter`: opens a file outside the project, filters for it by name, confirms, and asserts the correct path is opened. - Updated `test_search_results_refreshed_on_standalone_file_creation`: the fix correctly promotes single-file worktree files to `Match::History`, which activates `skip_focus_for_active_in_search` when the file is currently open. The test now asserts the match type directly and closes the picker with `menu::Cancel` instead of confirming. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed file picker failing to open non-project files when a filter is typed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
When a file is opened outside any project, Zed creates a single-file worktree for it where the file's relative path is
""(the worktree root IS the file). Typing to filter in the file picker (Ctrl-P) caused a crash:Error: opening project path "/home/user/foo.txt/foo.txt".Two bugs combined to produce this:
History lookup mismatch :
fuzzy_nucleodetectsroot_is_file = truefor single-file worktrees and moves the worktree root name intopath_match.path(so"" → "foo.txt").matching_history_itemsstored the entry under key""but looked it up by"foo.txt"→ miss → item dropped from history matches.Search confirm duplication : because the history match was dropped, the file appeared as
Match::Searchwithpath_match.path = "foo.txt". Confirming the constructedProjectPath { path: "foo.txt" }inside a worktree rooted at/home/user/foo.txt→ resolved to/home/user/foo.txt/foo.txt.Fix 1 adds a fallback empty-path lookup in
matching_history_itemsso single-file worktree entries are found correctly and deduplication suppresses the search duplicate. Fix 2 is defense-in-depth: if a single-file worktree file ever reachesthe
Match::Searchconfirm handler, it detectsis_single_file()and uses an empty path instead.Edit :
After further work, two additional edge cases were fixed:
Match::Searchsplit-open handling now uses the same single-file worktree path normalization as normal confirm. This prevents split-opening a single-file worktree search result from resolvingnotes.txtinside/path/to/notes.txtas/path/to/notes.txt/notes.txt.History matching now still includes root names for single-file worktrees when
project_panel.hide_root = true. Normal folder worktree roots remain hidden in this mode, but single-file worktrees need their root name included because the root name is the filename users type into the picker.Additional test coverage:
test_non_project_file_matches_history_with_hidden_rootfor thehide_root=truehistory matching edge case.test_single_file_search_result_split_openfor split-opening a single-file worktree search result.Closes #54934
Manual test after fix below :
Screencast.from.2026-04-26.23-58-00.webm
How to Review
crates/file_finder/src/file_finder.rs: Two targeted changes:matching_history_items(~line 757): added.or_elsefallback that retries the candidates lookup with an empty path when the first lookup misses, covering theroot_is_filekey mismatch for single-file worktrees.Match::Searchconfirm handler (~line 1640): checkswt.read(cx).is_single_file()and substitutesRelPath::empty()forpath_match.pathto prevent duplication.crates/file_finder/src/file_finder_tests.rs— Two test changes:test_non_project_file_open_with_filter: opens a file outside the project, filters for it by name, confirms, and asserts the correct path is opened.test_search_results_refreshed_on_standalone_file_creation: the fix correctly promotes single-file worktree files toMatch::History, which activatesskip_focus_for_active_in_searchwhen the file is currently open. The test now asserts the match type directly and closes the picker withmenu::Cancelinstead of confirming.Self-Review Checklist
Release Notes: