matchmaker-cli 0.0.11

Command-line interface for the matchmaker fuzzy finder
# Matchmaker [![Crates.io]https://img.shields.io/crates/v/matchmaker-cli]https://crates.io/crates/matchmaker-cli [![License: AGPL v3]https://img.shields.io/badge/License-AGPL%20v3-blue.svg]https://github.com/squirreljetpack/matchmaker/blob/main/matchmaker-cli/LICENSE

Matchmaker is fast, configurable and intuitive fuzzy searcher.

It takes inspiration from [fzf](https://github.com/junegunn/fzf) in features and design, but reimagines the user experience. Built from the ground up in Rust using modern libraries, it provides a maximally cohesive, performant and versatile experience, in a minimal amount of code. It's simple to get started, give it a try! [^10]

![screen1](https://github.com/Squirreljetpack/matchmaker/blob/main/matchmaker-lib/assets/screen1.png)

## Features

- Matching with [nucleo]https://github.com/helix-editor/nucleo.
- _Fully_ configurable via a type-checked [toml file]./matchmaker-cli/assets/config.toml. [^11]
- A minimal yet powerful [syntax]./matchmaker-cli/assets/docs/options.md for overriding the configuration on the command line.
- Interactive preview supports color, scrolling, wrapping, multiple layouts, and even maximizing.
- Most of the familiar actions from [fzf]https://github.com/junegunn/fzf, as well as several new ones[^12].
- Mouse (location aware) scrolling! Horizontal scrolling! Grapheme-aware input wrapping!
- Split input lines into multiple columns, that you can individually filter on (using the syntax: `%col query`), hide, and highlight.[^14]
- Define `Execute/Preview/Print/Accept` actions based on the current item using [Templating]https://github.com/Squirreljetpack/matchmaker/blob/main/matchmaker-cli/assets/docs/template.md (yes, columns are supported here too).
- All the dynamic UI support you could hope for: preview offsets, styled status lines, responsive header tables, wrapped footers, active and inactive column colors, stacked columns, multiple preview layouts[^15]... even overlays! (in the library).
- Bind keys to multiple actions, bind actions to mouse triggers, bind actions to event triggers, bind keys to rebind keys, bind keys to modify the configuration, bind keys to run a shell script and use its output to more keys[^16], bind keys to set the header, footer, status, input, bind keys to semantic triggers, bind semantic triggers to actions, bind keys to -- wait nope thats about it.
- oh yeah, and `mm --last-key` gives you the last key that was pressed in a previous run of the program.[^13]
- Available as a rust library to use in your own code!

On the way:

- Matching with [frizbee]https://github.com/saghen/frizbee, a faster, typo-resistant matching algorithm.

[^10]: Sample configurations are on the roadmap, and contributions are very welcome!

[^11]: The benefits of a structured, hierarchical, global baseline configuration are many, including but not limited to the fact that toml strings make it much easier to bind keys to complex shell scripts.

[^12]: Custom exit codes, select all (`CycleAll`), PageUp/Down, Show Help, Cycle columns (`NextColumn`), Multiple input commands (`NextReload`), etc. ...

[^13]: This is useful for when you want to write a shell script that dispatches different actions on the output of matchmaker based on the key that was pressed.

[^14]: If no column names are configured, the autogenerated column names are sequential: 1, 2, 3...

[^15]: I like this so much i had to mention it twice

[^16]: you can't do this yet

## Installation

```sh
cargo install matchmaker-cli

# or grab a release from the releases page with bonus features.
```

Pass it some items:

```sh
find . | mm
```

> [!NOTE]
> The [default]./matchmaker-cli/assets/config.toml 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)

Matchmaker options are hierarchical, although most categories live at the top level:

```toml
[preview]
    show = true
    wrap = true
    header_lines = 3 # sticky the top 3 lines

# Full specification of (the default values of) a single layout. Multiple layouts can be specified.
[[preview.layout]]
    command    = ""
    side       = "right"
    percentage = 60
    min        = 30
    max        = 120
```

The structure of the config file is defined [here](./matchmaker-cli/src/config.rs)[^1], and the full specification lives [here](./matchmaker-lib/src/config.rs)[^2].

Options can be overridden on the command line, where abbreviations are supported:

```sh
mm --config ~/.config/matchmaker/alternate.toml p.l "cmd=[echo {}] p=50 max=20" cmd "ls" o "'{}'"

# 1. Start mm with an alternate config, as well as with the following overrides:
# 2. List the contents of the current directory by executing `ls`
# 3. Show the current item name in the preview pane
# 4. Set a preferred percentage of 50 for the preview pane, and a maximum column width of 20 for the preview pane
# 5. Output the result wrapped in single quotes
```

[^1]: Note that the flatten attribute on the render field means that the subfields of RenderConfig should be specified at the top level of the toml (i.e. your toml should specify `[results]` instead of `[render.results]`).

[^2]: and parts of it [here]./matchmaker-lib/src/config-types.rs.

### Keybindings

Actions can be defined in your `config.toml` or on the command line.

The list of currently supported actions can be found [here](./matchmaker-lib/src/action.rs) and [here](./matchmaker-cli/src/action.rs) or from `mm --options`.

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

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

## CLI

See [here](./matchmaker-cli/assets/docs/options.md) for the command-line syntax.

Matchmaker aims to achieve feature-parity with fzf (though not necessarily by the same means). If there's any specific feature that you'd like to see, open an issue!

## 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(())
}
```

For more information, check out the [examples](./matchmaker-lib/examples/) and [Architecture.md](./matchmaker-lib/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