Skip to content

Add fuzzy_nucleo crate for order independent file finder search#51164

Merged
yara-blue merged 13 commits intozed-industries:mainfrom
11happy:fuzzy
Apr 7, 2026
Merged

Add fuzzy_nucleo crate for order independent file finder search#51164
yara-blue merged 13 commits intozed-industries:mainfrom
11happy:fuzzy

Conversation

@11happy
Copy link
Copy Markdown
Contributor

@11happy 11happy commented Mar 10, 2026

Closes #14428

Before you mark this PR as ready for review, make sure that you have:

  • Added a solid test coverage and/or screenshots from doing manual testing
screencast.mp4
  • Done a self-review taking into account security and performance aspects
  • Aligned any UI changes with the UI checklist

Release Notes:

  • Adds a new fuzzy_nucleo crate that implements order independent path
    matching using the nucleo library. currently integrated for file finder.

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Mar 10, 2026
Comment thread crates/fuzzy_nucleo/LICENSE_GPL Outdated
@dinocosta dinocosta added the area:file finder Feedback for file management, navigation, etc label Mar 10, 2026
Copy link
Copy Markdown
Contributor Author

@11happy 11happy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have kept lot of data structures & methods similar to what already exist in current fuzzy crate & also took reference from this PR #37123 to implement path_match_helper

Comment thread crates/file_finder/src/file_finder.rs
Comment thread crates/fuzzy_nucleo/src/paths.rs Outdated
@yara-blue
Copy link
Copy Markdown
Member

hey @11happy I had a quick look and this looks pretty much great. I've set some time apart for a thorough review early next week but I expect we can merge this soon thereafter.

Thank you so much for this work, I've wanted this for quiet a while!

@zelenenka zelenenka added the guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions label Mar 16, 2026
Comment thread crates/fuzzy_nucleo/src/paths.rs
Comment thread crates/fuzzy_nucleo/src/paths.rs Outdated
Comment thread crates/fuzzy_nucleo/src/paths.rs Outdated
Comment thread crates/fuzzy_nucleo/src/paths.rs
@yara-blue
Copy link
Copy Markdown
Member

just some comments not done yet, ill get back to this tomorrow!

@yara-blue
Copy link
Copy Markdown
Member

I've been looking at the relative ordering. Here we would ideally have the file audio_settings.rs listed before the other items. I am kinda surprised its not at the top given you have the path length penalty in there.

I do not think you are using nucleo wrong, we might just need some extra bonuses/penalties here and there to get it perfect.

That could be a separate PR, could be in this one. How do you feel about playing around a little and getting it perfect?

image

Copy link
Copy Markdown
Member

@yara-blue yara-blue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small concerns otherwise looks great. Let me know when it's ready for another review :)

@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Mar 20, 2026

A few small concerns otherwise looks great. Let me know when it's ready for another review :)

Sure Thank you for the review, I will ping once I have addressed all the comments.

that could be a separate PR, could be in this one. How do you feel about playing around a little and getting it perfect

I think its better to adress in this one only, I will try to fix this as well.

Thank you

@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Mar 23, 2026

ping! @yara-blue , I have addressed all the comments & added a bonus as well, should rank settings audio correctly have checked locally.

Thank you

@github-actions github-actions Bot added Size L large-pr Automation related label for detecting large contributor PRs labels Mar 23, 2026
@github-actions
Copy link
Copy Markdown

📏 PR Size: 547 lines changed (Size L)

Please note: this PR exceeds the 400 LOC soft limit.

  • Consider splitting into separate PRs if the changes are separable
  • Ensure the PR description includes a guided tour in the "How to Review" section so reviewers know where to start

@yara-blue
Copy link
Copy Markdown
Member

📏 PR Size: 547 lines changed (Size L)

Please note: this PR exceeds the 400 LOC soft limit.

* Consider **splitting** into separate PRs if the changes are separable

* Ensure the PR description includes a **guided tour** in the "How to Review" section so reviewers know where to start

you may ignore this :)

Copy link
Copy Markdown
Member

@yara-blue yara-blue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code is looking good, Unfortunately I found regression compared to the current ranking:

this PR
image

mainline Zed:
image

As fuzzy finding is a method of navigation for a large user base we must be sure not to regress there (they would get pretty annoyed).

We can still get this over the line though! I think what we need is to extend the test-suite for the file finder comparing the current fuzzy finder and this one. With the above (and the audio settings example) we have at least two test cases already. Maybe you can find a few more?

Let me know what you think.

@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Mar 23, 2026

Code is looking good, Unfortunately I found regression compared to the current ranking:

this PR image

mainline Zed: image

As fuzzy finding is a method of navigation for a large user base we must be sure not to regress there (they would get pretty annoyed).

We can still get this over the line though! I think what we need is to extend the test-suite for the file finder comparing the current fuzzy finder and this one. With the above (and the audio settings example) we have at least two test cases already. Maybe you can find a few more?

Let me know what you think.

sure let me add some more test cases

@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Mar 23, 2026

added some more tests : ) & now those pointed above are addressed.

Comment thread crates/fuzzy_nucleo/src/paths.rs Outdated
@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Mar 29, 2026

I have fixed the edge cases , replaced single pattern matching (Pattern::new) with multi atom matching (spliting query on whitespace into separate Atoms, each matched independently). Also filename bonus is much better now it scores each atom, also since filename bonus is handling things along with nucleo scores we no longer need is_filename_match in cmp_matches. All test cases passing! : )

Comment thread crates/fuzzy_nucleo/src/paths.rs Outdated
Comment thread crates/fuzzy_nucleo/src/paths.rs Outdated
Copy link
Copy Markdown
Member

@yara-blue yara-blue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really elegant solution with the Atoms!

I'm gonna daily drive this for two days and see if I can find any other regression. If you could do that minor file_name refactor then we should be good.

Oh and see my note on indices. You can absolutely leave them as is however there are many more pickers to make fuzzy so it might help us in the future to have this code as readable as possible :)

@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Apr 1, 2026

is the test failure related to this PR?

2026-04-01T12:27:42+00:00 INFO  [extension_host] extensions updated. loading 1, reloading 0, unloading 0
    current_dir: /tmp/.tmpu3NJLY/work/test-extension
    command output: hello from a child process!
    test extension_store_test::test_extension_store_with_test_extension ... FAILED
failures:
failures:
        extension_store_test::test_extension_store_with_test_extension
    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 3 filtered out; finished in 29.78s
stderr ───
thread 'extension_store_test::test_extension_store_with_test_extension' (22133) panicked at crates/extension_host/src/extension_store_test.rs:903:5:
assertion `left == right` failed
      left: []
     right: ["foo: fn() -> Result(Nil, Error)", "bar.baz: fn(List(a)) -> a", "Quux: fn(String) -> T", "my_string: String"]
    stack backtrace:
       0: __rustc::rust_begin_unwind
                 at /rustc/e408947bfd200af42db322daf0fadfe7e26d3bd1/library/std/src/panicking.rs:689:5
       1: core::panicking::panic_fmt
                 at /rustc/e408947bfd200af42db322daf0fadfe7e26d3bd1/library/core/src/panicking.rs:80:14
       2: core::panicking::assert_failed_inner
                 at /rustc/e408947bfd200af42db322daf0fadfe7e26d3bd1/library/core/src/panicking.rs:439:17
       3: core::panicking::assert_failed
                 at /home/runner/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panicking.rs:394:5
       4: extension_host::extension_store_test::test_extension_store_with_test_extension::__test_extension_store_with_test_extension::{{closure}}
                 at ./src/extension_store_test.rs:903:5
       5: gpui::executor::ForegroundExecutor::block_test::{{closure}}
                 at /home/runner/work/zed/zed/crates/gpui/src/executor.rs:440:36
       6: <scheduler::test_scheduler::TestScheduler as scheduler::Scheduler>::block
                 at /home/runner/work/zed/zed/crates/scheduler/src/test_scheduler.rs:538:35
       7: gpui::executor::ForegroundExecutor::block_test
                 at /home/runner/work/zed/zed/crates/gpui/src/executor.rs:447:19
       8: extension_host::extension_store_test::test_extension_store_with_test_extension::{{closure}}
                 at ./src/extension_store_test.rs:537:1
       9: gpui::test::run_test::{{closure}}
                 at /home/runner/work/zed/zed/crates/gpui/src/test.rs:88:17
      10: std::panicking::catch_unwind::do_call
                 at /home/runner/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:581:40
      11: __rust_try
      12: std::panicking::catch_unwind
                 at /home/runner/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:544:19
      13: std::panic::catch_unwind
                 at /home/runner/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:359:14
      14: gpui::test::run_test
                 at /home/runner/work/zed/zed/crates/gpui/src/test.rs:85:26
      15: extension_host::extension_store_test::test_extension_store_with_test_extension
                 at ./src/extension_store_test.rs:537:1
      16: extension_host::extension_store_test::test_extension_store_with_test_extension::{{closure}}
                 at ./src/extension_store_test.rs:537:14
      17: core::ops::function::FnOnce::call_once
                 at /home/runner/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
      18: core::ops::function::FnOnce::call_once
                 at /rustc/e408947bfd200af42db322daf0fadfe7e26d3bd1/library/core/src/ops/function.rs:250:5
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ?
    ```

11happy and others added 12 commits April 3, 2026 19:59
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Apr 3, 2026

Hii @yara-blue are there any more changes required from my end, Also I have it rebased with main.
Thank you : )

@yara-blue
Copy link
Copy Markdown
Member

Hii @yara-blue are there any more changes required from my end, Also I have it rebased with main.
Thank you : )

Sorry its taking so long, I'm trying to find time to check why that test is failing, should find some this week!

@yara-blue yara-blue self-requested a review April 7, 2026 10:04
@yara-blue
Copy link
Copy Markdown
Member

rebase fixed it! 🥳

Lets merge!

@yara-blue yara-blue merged commit 9343882 into zed-industries:main Apr 7, 2026
30 checks passed
@yara-blue
Copy link
Copy Markdown
Member

Feel free to tackle other pickers if you want :)

@11happy
Copy link
Copy Markdown
Contributor Author

11happy commented Apr 7, 2026

Thank you for merging this, I will start work on another picker.

MasoudAlali pushed a commit to MasoudAlali/zed-ide that referenced this pull request Apr 7, 2026
…industries#51164)

Closes zed-industries#14428 

Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing


https://github.com/user-attachments/assets/7e0d67ff-cc4e-4609-880d-5c1794c64dcf


- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- Adds a new `fuzzy_nucleo` crate that implements order independent path
matching using the `nucleo` library. currently integrated for file
finder.

---------

Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
@feitreim
Copy link
Copy Markdown
Contributor

feitreim commented Apr 8, 2026

Hey @11happy, at @yara-blue suggestion I've been experimenting with using the fuzzy_nucleo crate to do some matching in the remote project picker while working on this issue: #53318

I implemented a more plain string matching than the path specific setup you implemented here, and I noticed that it was quite a bit slower than fuzzy in some scenarios, while I thought this was due to my string matching implementation primarily, just out of curiosity I thought I would try benchmarking the path matching that was originally setup and it actually performed even worse relative to the fuzzy version than my string matching did.

Paths:
Screenshot 2026-04-08 at 3 20 33 PM

Strings:
Screenshot 2026-04-08 at 3 21 26 PM

It does seem like the main reason for this is that fuzzy is just doing some other optimizations (especially because multiple atoms seems to be a huge factor here) that we can bring over to fuzzy_nucleo.

I was wondering if you had done any benchmarking of your own that showed different results? Or is it just a difference in functionality that I'm missing the nuance of. Totally possible that there is a piece I'm missing in my benchmark or other understanding of the topic. in the meantime i'm going to look into optimizing fuzzy_nucleo and see what kind of changes it might benefit from.

(I do understand that a lot of the performance hit, esp for the multi-word case is due to the atom thing, which I do understand the reasoning behind, I would just expect ~2x cost not ~10x)

@yara-blue
Copy link
Copy Markdown
Member

I was wondering if you had done any benchmarking of your own that showed different results?

No :3, I kinda assumed that since Helix used it and Nucleo has benchmarks demonstrating its speed that we would be good. Thank you for helping out and comparing them!

Or is it just a difference in functionality that I'm missing the nuance of

Nucleo uses Smith-Waterman, which is really nice but more complex then the existing fuzzy implementation. So it makes sense for it to be a bit slower. Still 10x is a lot!

in the meantime i'm going to look into optimizing fuzzy_nucleo and see what kind of changes it might benefit from.

As long as the code stays readable optimizations are very welcome! Thank you and good luck!

@gee-forr
Copy link
Copy Markdown

I saw the release notes and was compelled to post a HUGE THANK YOU!!!

No matter how I tried, I could not rewire my muscle memory around this limitation compared to VSCode's search algo. THANK YOU THANK YOU THANK YOU!!!!!!!

piper-of-dawn pushed a commit to piper-of-dawn/zed that referenced this pull request Apr 25, 2026
…industries#51164)

Closes zed-industries#14428 

Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing


https://github.com/user-attachments/assets/7e0d67ff-cc4e-4609-880d-5c1794c64dcf


- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- Adds a new `fuzzy_nucleo` crate that implements order independent path
matching using the `nucleo` library. currently integrated for file
finder.

---------

Signed-off-by: Bhuminjay <bhuminjaysoni@gmail.com>
Signed-off-by: 11happy <soni5happy@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:file finder Feedback for file management, navigation, etc cla-signed The user has signed the Contributor License Agreement guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions large-pr Automation related label for detecting large contributor PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ordering of search tokens in file finder fuzzy match

7 participants