Crate nucleo_picker

Source
Expand description

§A generic fuzzy item picker

This is a generic picker implementation based on the nucleo::Nucleo matching engine. The crate allows you to incorporate an interactive fuzzy picker TUI (similar in spirit to the very popular fzf) into your own applications.

In short, initialize a Picker using PickerOptions and describe how the items should be represented by implementing Render, or use a built-in renderer.

For more complex use-cases and integration with an existing application, see the event module.

§Usage examples

For more usage examples, visit the examples folder on GitHub.

§fzf example

Run this example with cat myfile.txt | cargo run --release --example fzf.

//! # Simple `fzf` clone
//!
//! Read lines from `stdin` in a streaming fashion and populate the picker, imitating the basic
//! functionality of [fzf](https://github.com/junegunn/fzf).
use std::{
    io::{self, IsTerminal},
    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 || {
        let stdin = io::stdin();
        if !stdin.is_terminal() {
            for line in stdin.lines() {
                // silently drop IO errors!
                if let Ok(s) = line {
                    injector.push(s);
                }
            }
        }
    });

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

§find example

Run this example with cargo run --release --example find ~.

//! # Non-blocking `find`-style picker
//!
//! Iterate over directories to populate the picker, but do not block so that
//! matching can be done while the picker is populated.
use std::{borrow::Cow, env::args, io, path::PathBuf, thread::spawn};

use ignore::{DirEntry, WalkBuilder, WalkState};
use nucleo_picker::{nucleo::Config, PickerOptions, Render};

pub struct DirEntryRender;

impl Render<DirEntry> for DirEntryRender {
    type Str<'a> = Cow<'a, str>;

    /// Render a `DirEntry` using its internal path buffer.
    fn render<'a>(&self, value: &'a DirEntry) -> Self::Str<'a> {
        value.path().to_string_lossy()
    }
}

fn main() -> io::Result<()> {
    let mut picker = PickerOptions::default()
        // See the nucleo configuration for more options:
        //   https://docs.rs/nucleo/latest/nucleo/struct.Config.html
        .config(Config::DEFAULT.match_paths())
        // Use our custom renderer for a `DirEntry`
        .picker(DirEntryRender);

    // "argument parsing"
    let root: PathBuf = match args().nth(1) {
        Some(path) => path.into(),
        None => ".".into(),
    };

    // populate from a separate thread to avoid locking the picker interface
    let injector = picker.injector();
    spawn(move || {
        WalkBuilder::new(root).build_parallel().run(|| {
            let injector = injector.clone();
            Box::new(move |walk_res| {
                if let Ok(dir) = walk_res {
                    injector.push(dir);
                }
                WalkState::Continue
            })
        });
    });

    match picker.pick()? {
        // the matched `entry` is `&DirEntry`
        Some(entry) => println!("Path of selected file: '{}'", entry.path().display()),
        None => println!("No file selected!"),
    }

    Ok(())
}

Re-exports§

pub use nucleo;

Modules§

error
Errors during interactive picker usage
event
Extended event handling
render
Renderers for use in a Picker

Structs§

Injector
A handle which allows adding new items to a Picker.
Picker
A fuzzy matching interactive item picker.
PickerOptions
Specify configuration options for a Picker.

Traits§

Render
A trait which describes how to render objects for matching and display.