matchmaker-lib 0.0.1

A fuzzy finder for the terminal, powered by nucleo
# m&m [![Crates.io](https://img.shields.io/crates/v/match-maker)](https://crates.io/crates/match-maker) [![License](https://img.shields.io/github/license/squirreljetpack/matchmaker)](https://github.com/squirreljetpack/matchmaker/blob/main/LICENSE)

Matchmaker is a fuzzy searcher, powered by nucleo and written in rust.

(pitch + fzf credit: todo)

## Features

- Matching with [nucleo](https://github.com/helix-editor/nucleo).
- Declarative configuration sourced from a [toml file](./assets/config.toml). (Cli parsing not yet implemented.)
- Interactive preview supports color, scrolling, wrapping, multiple layouts, and even entering into an interactive view.
- [FZF](https://github.com/junegunn/fzf)-inspired actions.
- Column support: Split input lines into multiple columns, that you can dynamically search, filter, highlight, return etc.
- Available as a rust library to use in your own code.

## Installation

```sh
cargo install match-maker # note the hyphen!
```

Pass it some items:

```sh
find . | mm
```

> [!NOTE]
> The default input and preview commands rely on fd, bat and eza. For an optimal experience, install them or update your configuration.

## Configuration

To begin, you can dump the default configuration to a file:

```sh
matchmaker --dump-config
```

The default locations are in order:

- `~/.config/matchmaker/config.toml` (If the folder exists already).
- `{PLATFORM_SPECIFIC_CONFIG_DIRECTORY}/matchmaker` (Generally the same as above when on linux)

### Keybindings

All actions must be defined in your `config.toml`.

The list of currently supported actions can be found [here](./src/action.rs).

To get the names of keys, type `matchmaker --test-keys`.

In addition to keys, actions can also be bound to Events and Crossterm events (check your default config for details).

## Library

Matchmaker can also be used as a library.

```sh
cargo add matchmaker
```

### Example

Here is how to use `Matchmaker` to select from a list of strings.

```rust
use matchmaker::nucleo::{Indexed, Worker};
use matchmaker::{MatchError, Matchmaker, Result, Selector};

#[tokio::main]
async fn main() -> Result<()> {
    let items = vec!["item1", "item2", "item3"];

    let worker = Worker::new_single_column();
    worker.append(items);
    let selector = Selector::new(Indexed::identifier);
    let mm = Matchmaker::new(worker, selector);

    match mm.pick_default().await {
        Ok(v) => {
            println!("{}", v[0]);
        }
        Err(err) => match err {
            MatchError::Abort(1) => {
                eprintln!("cancelled");
            }
            _ => {
                eprintln!("Error: {err}");
            }
        },
    }

    Ok(())
}
```

### Dynamic handlers

Some features such as the execute, reload, and print actions, and even the previewer do not have their behavior defined directly in the render loop.

Instead, they are attached as handlers to the Matchmaker, which are triggered by certain events and interrupts generated by the loop.

Some actions can generate these triggers, as well usually performing a minimal amount of other logic.

For example, the `Preview(bat {})` command generates a `PreviewChanged` event, and leaves the string contents as a payload in the render state. This render state is exposed to the handler, and is used to spawn the command which is then displayed to preview. The `Execute` action is another example: it simply leaves the tui before raising the execute interrupt, then re-enters before the next render -- the handler associated to the interrupt is what spawns the process in the main app. As a rule, any action with effects beyond the UI has its logic defined seperately, and is therefore be fully amenable to the needs of the application.

For more specific requirements, the set of actions can be extended with a type implementing `ActionExt`, on which a handler with mutable access to the UI state can be registered. Additionally, [`PickOptions`](./src/matchmaker.rs#L417) also supports registering an [`ext_aliaser`](./src/matchmaker.rs#L481-L484) which can be used transform actions before they are processed.

For more information, check out the [examples](./examples/) and [Architecture.md](./ARCHITECTURE.md)

# See also

- [junegunn/fzf](https://github.com/junegunn/fzf)
- [helix-editor/nucleo](https://github.com/helix-editor/nucleo)
- [skim-rs/skim](https://github.com/skim-rs/skim)
- [autobib/nucleo-picker](https://github.com/autobib/nucleo-picker)
- [alexpasmantier/television](https://github.com/alexpasmantier/television)
- [helix-editor/helix](https://github.com/helix-editor/helix)
- [Canop/crokey](https://github.com/Canop/crokey)