Skip to content

a fuzzy picker tui library for rust

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

autobib/nucleo-picker

Repository files navigation

Current crates.io release Documentation

nucleo-picker

Yet another fuzzy picker library. This library provides a TUI for the nucleo crate. The picker interface is similar to the very popular fzf command-line tool, but rather than act as a standalone binary, this provides a Rust library which allows you to incorporate a picker interface into your own application.

See the examples directory for implementation examples, or try out the sample find/fzf implementation by cloning the repository and running cargo run --release --example find ~.

If you are looking for documentation for interactive usage of the picker, see the USAGE.md file.

If you are looking for a list of recent changes, see the CHANGELOG.md file.

Features

  • Highly optimized matching, courtesy of nucleo.
  • Robust rendering:
    • Match highlighting with automatic scroll-through.
    • Careful Unicode handling using Unicode text segmentation and Unicode width.
    • Correctly handle multi-line or overflowed items.
    • Responsive terminal rendering with batched keyboard input handling.
  • Ergonomic API:
    • Non-blocking to match on streaming input.
    • Generic Picker for any type T which is Send + Sync + 'static.
    • Customizable rendering of crate-local and foreign types with the Render trait.

Example

Implement a heavily simplified fzf clone in 30 lines of code. Try it out with:

cargo build --release --example fzf
cat myfile.txt | ./target/release/examples/fzf

The code to create the binary:

use std::{
    io::{self, BufRead},
    process::exit,
    thread::spawn,
};

use nucleo_picker::{render::StrRenderer, Picker};

fn main() -> io::Result<()> {
    let mut picker = Picker::new(StrRenderer);

    let injector = picker.injector();
    spawn(move || {
        for line in io::stdin().lock().lines() {
            match line {
                Ok(s) => injector.push(s),
                Err(_) => {}
            }
        }
    });

    match picker.pick()? {
        Some(it) => println!("{it}"),
        None => exit(1),
    }
    Ok(())
}

Related crates

This crate mainly exists as a result of the author's annoyance with pretty much every fuzzy picker TUI in the rust ecosystem.

  • skim's Arc<dyn SkimItem> is inconvenient since the original item cannot be canonically recovered from the match (requires Arc down-casting). skim also has a large number of dependencies and is designed more as a binary than a library.
  • fuzzypicker is based on skim and inherits skim's problems.
  • nucleo-ui only has a blocking API and only supports matching on String. It also seems to be un-maintained.
  • fuzzy-select only has a blocking API.
  • dialoguer FuzzySelect only has a blocking API and only supports matching on String. The terminal handling also has a few strange bugs.

Disclaimer

The feature set of this library is quite minimal (by design) but may be expanded in the future. There are a currently a few known problems which have not been addressed (see the issues page on GitHub for a list).

About

a fuzzy picker tui library for rust

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Languages