# ThumbPick

ThumbPick is a product of my procrastination. It's a lightweight,
keyboard-centric image picker written in Rust and GTK4. It scans a directory for
images, generates thumbnails asynchronously, and allows for rapid filtering and
selection.

It's designed to be used in scripts or pipelines. In particular, it does _one_
thing: it displays images, it allows you to search through them, and it returns
their path. And it does so quickly. All other tools I'd used before either
lacked one of these requirements, or also did a bunch more things I didn't need.

![screenshot](assets/screenshot.png)

## Features

- **Fast Thumbnail Generation**: Uses `rayon` for parallel image decoding and
  `walkdir` for efficient directory traversal.
- **Non-Blocking UI**: Image loading occurs on a separate thread, sending
  results to the main GTK loop via async channels to ensure the interface never
  freezes.
- **Type-to-Filter**: There is no search bar. Just start typing to filter images
  by filename. An overlay label appears dynamically at the bottom of the window
  to show the current query.
- **Scriptable Output**: Pressing `Enter` prints the selected image's full path
  to `stdout` and exits with status 0, making it easy to pipe into other tools.

## Usage

```bash
thumbpick <directory> [-v | --vi-mode]
```

**Example:** Pipe the selected image to `feh` or a wallpaper setter:

```bash
# Set wallpaper with the selected image
swww img "$(thumbpick ~/Pictures/Wallpapers)"
```

## Controls

Regardless of the mode you're in, `Escape` will also close the window if you're
not currently searching.

| Input            | Action                                     |
| ---------------- | ------------------------------------------ |
| **Alphanumeric** | Append character to search                 |
| **Backspace**    | remove last character from filter (duh)    |
| **Escape**       | clear active filter                        |
| **Double Click** | Open image immediately with `xdg-open`     |
| **Enter**        | Print selected path to `stdout` and `exit` |

**Vi Mode (`-v | --vi-mode`)**

| Input             | Action                                                                        |
| ----------------- | ----------------------------------------------------------------------------- |
| **h / j / k / l** | Navigate selection (Left/Down/Up/Right)                                       |
| **/**             | Enter search mode                                                             |
| **Escape**        | Exit search mode / Clear active filter                                        |
| **Backspace**     | Remove last char / Exit search if empty                                       |
| **Double Click**  | Open image immediately with `xdg-open`                                        |
| **Enter**         | Print selected path to `stdout` and `exit` / Exit search mode, keeping filter |

All options present in the config file (see below) can also be set with env vars. The env vars are derived as follows:
`THUMBPICK_<option name in caps>`

For nested options, use two underscores. Examples below.
```
THUMBPICK_KEYS__UP=t thumbpick
THUMBPICK_THUMB_SIZE=150 thumbpick
```

## Installation

### Nix (via flakes)

This project uses `naersk` and `fenix` to provide a reproducible build
environment.

**Run directly:**

```bash
nix run github:soliprem/thumbpick <directory>
# or
nix run github:soliprem/thumbpick -- <directory> -v
```

**Install:**

Add the flake to your inputs

```nix
inputs = {
  nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  thumbpick = {
        url = "github:soliprem/thumbpick";
        inputs.nixpkgs.follows = "nixpkgs";
    };
...
};
```

And the package

```nix
environment.systemPackages = with pkgs; [
    ...
    inputs.thumbpick.packages.${pkgs.stdenv.hostPlatform.system}.default
    ...
];
```

Ready to go!

### Cargo

```bash
cargo install thumbpick
```

#### From Source

Ensure you have GTK4 development libraries installed on your system (should be
`gtk4`, `glib2`, `gdk-pixbuf2`, `cairo`, `pango`).

```bash
git clone https://github.com/soliprem/thumbpick
cd thumbpick
cargo install --path .
```

Or run directly without installing:

```bash
cargo run --release -- <directory>
```

## Configuration

Thumbpick looks for a configuration file at `~/.config/thumbpick/config.toml`.

Below is the default configuration. You can copy this to your config file to
override specific values.

`dir_path` supports shell expansion, so you can use `~` (e.g., `~/Pictures`) or
environment variables (e.g., `$XDG_DATA_HOME/wallpapers`).

```toml
# Default: false. Set to true to enable Vim-style navigation and behavior.
vi_mode = false

# Start directory. Defaults to current directory if not set.
dir_path = "." 

# Thumbnail size in pixels.
thumb_size = 200

[keys]
# Navigation
up = "k"
left = "h"
down = "j"
right = "l"

# Actions
quit = "Escape"
search = "slash"    # "/" key
select = "Return"   # Enter key

# Jumping
go_top = "g"        # Press 'g' twice in vi_mode
go_bottom = "G"     # Shift+g
line_start = "asciicircum" # "^" key
line_end = "dollar"        # "$" key
```

### Keys

Key names use the standard GDK key names. This means they are case sensitive.
Common control keys have specific capitalized names, like `Escape` `Return`
`Tab` ...

You can find a
[list of key names here](https://github.com/GNOME/gtk/blob/main/gdk/keynames.txt).
You can find out a key's keyname by using programs like `wev`. This is an
example of wev's output, typing the `Enter` key.

```bash
wev
...
[        11:    xdg_toplevel] configure: width: 1256; height: 1408
                      tiled-left tiled-right tiled-top tiled-bottom activated
[        10:     xdg_surface] configure: serial: 2888898
[        16:     wl_keyboard] key: serial: 2888899; time: 39294524; key: 36; state: 1 (pressed)
                      sym: Return       (65293), utf8: '\r'
[        16:     wl_keyboard] key: serial: 2888900; time: 39294582; key: 36; state: 0 (released)
                      sym: Return       (65293), utf8: ''
```

Notice the `sym: Return`. This generally works for me.

## License

GNU General Public License v3.0.

## Credits

[waypaper](https://github.com/anufrievroman/waypaper) and
[waytrogen](https://github.com/nikolaizombie1/waytrogen) are massive design
inspirations. They're also just better projects if you also want the program to
handle setting the background automatically and don't want to script it
yourself.
