Crate nucleo_matcher

source ·
Expand description

nucleo_matcher is a low level crate that contains the matcher implementation used by the high level nucleo crate.

NOTE: If you are building an fzf-like interactive fuzzy finder that is meant to match a reasonably large number of items (> 100) using the high level nucleo crate is highly recommended. Using nucleo-matcher directly in you ui loop will be very slow. Implementing this logic yourself is very complex.

The matcher is hightly optimized and can significantly outperform fzf and skim (the fuzzy-matcher crate). However some of these optimizations require a slightly less convenient API. Be sure to carefully read the documentation of the Matcher to avoid unexpected behaviour.

§Examples

For almost all usecases the pattern API should be used instead of calling the matcher methods directly. Pattern::parse will construct a single Atom (a single match operation) for each word. The pattern can contain special characters to control what kind of match is performed (see AtomKind).

let paths = ["foo/bar", "bar/foo", "foobar"];
let mut matcher = Matcher::new(Config::DEFAULT.match_paths());
let matches = Pattern::parse("foo bar", CaseMatching::Ignore, Normalization::Smart).match_list(paths, &mut matcher);
assert_eq!(matches, vec![("foo/bar", 168), ("bar/foo", 168), ("foobar", 140)]);
let matches = Pattern::parse("^foo bar", CaseMatching::Ignore, Normalization::Smart).match_list(paths, &mut matcher);
assert_eq!(matches, vec![("foo/bar", 168), ("foobar", 140)]);

If the pattern should be matched literally (without this special parsing) Pattern::new can be used instead.

let paths = ["foo/bar", "bar/foo", "foobar"];
let mut matcher = Matcher::new(Config::DEFAULT.match_paths());
let matches = Pattern::new("foo bar", CaseMatching::Ignore, Normalization::Smart, AtomKind::Fuzzy).match_list(paths, &mut matcher);
assert_eq!(matches, vec![("foo/bar", 168), ("bar/foo", 168), ("foobar", 140)]);
let paths = ["^foo/bar", "bar/^foo", "foobar"];
let matches = Pattern::new("^foo bar", CaseMatching::Ignore, Normalization::Smart, AtomKind::Fuzzy).match_list(paths, &mut matcher);
assert_eq!(matches, vec![("^foo/bar", 188), ("bar/^foo", 188)]);

If word segmentation is also not desired, a single Atom can be constructed directly.

let paths = ["foobar", "foo bar"];
let mut matcher = Matcher::new(Config::DEFAULT);
let matches = Atom::new("foo bar", CaseMatching::Ignore, Normalization::Smart, AtomKind::Fuzzy, false).match_list(paths, &mut matcher);
assert_eq!(matches, vec![("foo bar", 192)]);

§Status

Nucleo is used in the helix-editor and therefore has a large user base with lots or real world testing. The core matcher implementation is considered complete and is unlikely to see major changes. The nucleo-matcher crate is finished and ready for widespread use, breaking changes should be very rare (a 1.0 release should not be far away).

Modules§

  • Utilities for working with (unicode) characters/codepoints
  • This module provides a slightly higher level API for matching strings.

Structs§

  • Configuration data that controls how a matcher behaves
  • A matcher engine that can execute (fuzzy) matches.

Enums§