Skip to content

Use nucleo-matcher for VSCode-style file search#12446

Draft
mtsgrd wants to merge 1 commit intomasterfrom
nucleo-file-search-vscode-style
Draft

Use nucleo-matcher for VSCode-style file search#12446
mtsgrd wants to merge 1 commit intomasterfrom
nucleo-file-search-vscode-style

Conversation

@mtsgrd
Copy link
Contributor

@mtsgrd mtsgrd commented Feb 19, 2026

Replace the previous skim-based fuzzy matcher with nucleo-matcher to
provide path-aware matching similar to VSCode's Cmd+P. The new
implementation:

  • swaps fuzzy-matcher for nucleo-matcher in Cargo.toml
  • bonuses for matches after '/', word boundaries and camelCase
    transitions
  • updates compute_match_score to combine nucleo's path score with a
    filename bonus and a mild depth penalty

Copilot AI review requested due to automatic review settings February 19, 2026 18:26
@vercel
Copy link

vercel bot commented Feb 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gitbutler-web Ignored Ignored Preview Feb 19, 2026 9:58pm

Request Review

@github-actions github-actions bot added the rust Pull requests that update Rust code label Feb 19, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces the skim-based fuzzy matcher with nucleo-matcher to provide VSCode-style file search with better path-aware matching. The implementation improves the file search experience by adding intelligent bonuses for matches that occur after path separators, word boundaries, and camelCase transitions.

Changes:

  • Replaced fuzzy-matcher dependency with nucleo-matcher in Cargo.toml
  • Refactored compute_match_score to use nucleo's path-aware scoring with configurable bonuses
  • Updated scoring from i64 to u32 with saturating arithmetic and adjusted depth penalty from 50 to 10

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
crates/gitbutler-repo/Cargo.toml Swaps fuzzy-matcher dependency for nucleo-matcher 0.3
crates/gitbutler-repo/src/commands.rs Implements new scoring algorithm using nucleo-matcher with path-aware bonuses, removes separate filename bonus function, and updates find_files implementation with new matcher configuration
Comments suppressed due to low confidence (1)

crates/gitbutler-repo/src/commands.rs:333

  • The find_files function lacks test coverage despite this being a significant change in matching algorithm (from skim to nucleo-matcher). Consider adding tests that verify:
  1. Empty query behavior (should return all files)
  2. Basic fuzzy matching (e.g., "test" matches "src/test.rs")
  3. Path-aware matching (e.g., "s/t" matches "src/test.rs" due to path separator bonuses)
  4. CamelCase matching (e.g., "TC" matches "TestClass.rs")
  5. Result ordering based on match quality
  6. Depth penalty working correctly

This is especially important given that other functions in this crate (like create_wd_tree, hooks, etc.) have comprehensive test coverage in the tests/ directory.

    fn find_files(&self, query: &str, limit: usize) -> Result<Vec<String>> {
        static FAIR_QUEUE: Mutex<()> = Mutex::new(());
        let _one_at_a_time_to_prevent_races = FAIR_QUEUE.lock().unwrap();

        let workdir = self.workdir_or_fail()?;

        // Matcher configured for path matching: bonuses after '/', at word
        // boundaries, and camelCase transitions.
        let mut matcher = Matcher::new(Config::DEFAULT.match_paths());

        // Pattern::parse supports multi-word matching (space-separated) and
        // smart case (lowercase = case-insensitive, any uppercase = case-sensitive).
        let pattern = Pattern::parse(query, CaseMatching::Smart, Normalization::Smart);
        let pattern_is_empty = pattern.atoms.is_empty();

        // Reusable buffer for Utf32Str conversion.
        let mut buf = Vec::new();

        let scored_files = WalkBuilder::new(&workdir)
            .git_exclude(true)
            .git_global(true)
            .git_ignore(true)
            .build()
            .filter_map(Result::ok)
            .filter(|entry| entry.file_type().is_some_and(|ft| ft.is_file()))
            .filter_map(|entry| {
                let relative_path = entry.path().strip_prefix(&workdir).ok()?;
                let path_str = relative_path.to_string_lossy();
                if pattern_is_empty {
                    return Some((0u32, path_str.to_string()));
                }
                let score = compute_match_score(
                    &pattern,
                    &mut matcher,
                    &path_str,
                    relative_path,
                    &mut buf,
                )?;
                Some((score, path_str.to_string()))
            })
            .sorted_by(|a, b| b.0.cmp(&a.0))
            .take(limit)
            .map(|(_, path)| path)
            .collect();

        Ok(scored_files)
    }

@mtsgrd mtsgrd force-pushed the nucleo-file-search-vscode-style branch 2 times, most recently from c6af82e to 1cf273e Compare February 19, 2026 21:06
Copilot AI review requested due to automatic review settings February 19, 2026 21:46
@mtsgrd mtsgrd force-pushed the nucleo-file-search-vscode-style branch from 1cf273e to 40b70ca Compare February 19, 2026 21:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 2 changed files in this pull request and generated 4 comments.

Replace the previous skim-based fuzzy matcher with nucleo-matcher to
provide path-aware matching similar to VSCode's Cmd+P. The new
implementation:

- swaps fuzzy-matcher for nucleo-matcher in Cargo.toml
- bonuses for matches after '/', word boundaries and camelCase
  transitions
- updates compute_match_score to combine nucleo's path score with a
  filename bonus and a mild depth penalty
@mtsgrd mtsgrd force-pushed the nucleo-file-search-vscode-style branch from 40b70ca to 3449232 Compare February 19, 2026 21:58
@mtsgrd mtsgrd marked this pull request as draft February 19, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants