- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| DESIGN.md | ||
| README.md | ||
mfer — Meme Finder
A fast, keyboard-driven fuzzy image search. Point it at a folder of images and summon a popup where you type to search, navigate the results, and copy a match to your clipboard in a single keystroke.
Search matches on filename plus automatically generated metadata (OCR'd text and image tags), so you can find that screenshot by what it says or looks like, not just by its filename.
mfer ~/Pictures/memes
Features
- Fuzzy search across filenames, OCR text, and image tags (orientation, aspect ratio, resolution, and dominant colors).
- Instant startup: a fast filesystem scan opens the UI immediately while OCR/tag indexing happens in the background and streams results in live.
- OCR (via
tesseract) to index any text present in the image, making manga frames and dialog screenshots searchable. - Thumbnails in the result list, plus a full-size preview while holding
<TAB>. - Persistent metadata cache (SQLite) so images are only OCR'd/tagged once.
- Multiple copy actions: copy the full path, the filename, or the image itself to the clipboard.
Requirements
- A Rust toolchain (Rust 1.85+,
edition = "2021"). tesseractonPATH(optional, but recommended) for OCR indexing. Without it, search falls back to filename + tags only.- OCR language data defaults to
eng; override with theMFER_OCR_LANGenvironment variable (e.g.MFER_OCR_LANG=eng+jpn).
- OCR language data defaults to
- A clipboard-capable environment:
- Linux / Wayland: a compositor implementing
wlr-data-control(KDE Plasma / KWin works out of the box; GNOME / Mutter does not). - Linux / X11, macOS, and Windows: supported natively.
- Linux / Wayland: a compositor implementing
Installation
From source:
git clone <repo-url> mfer
cd mfer
cargo build --release
The binary is written to target/release/mfer. Put it on your PATH, or
install it directly:
cargo install --path .
Usage
mfer [OPTIONS] <PATH>
PATH is the directory of images to search (scanned recursively).
Options
| Option | Long | Description |
|---|---|---|
-c |
--copy-image |
Set the default <ENTER> action to copy the image bitmap. |
-f |
--full-path |
Set the default <ENTER> action to copy the full path (this is the default). |
-s |
--short-path |
Set the default <ENTER> action to copy just the filename. |
--rebuild |
Rebuild the metadata index from scratch, ignoring the cache. | |
--no-ocr |
Disable OCR tagging. |
The -c/-f/-s flags only change what <ENTER> does. The one-off copy
actions below are always available regardless of the flags.
Key bindings
| Key | Action |
|---|---|
| Type | Fuzzy-filter the results. |
<Up> / <Down> |
Move the selection (the search box cursor stays in place). |
Ctrl+J / Ctrl+K |
Vim-style selection navigation. |
<Enter> |
Perform the configured default action (from the CLI flags). |
Ctrl+C |
Copy the full path of the selection. |
Ctrl+I |
Copy the image of the selection. |
Ctrl+N |
Copy the filename of the selection. |
Hold <TAB> |
Show a full-size preview of the selection. |
| Click a row | Select it (and trigger the default action). |
<ESC> |
Exit. |
| Click outside | Exit. |
On selection, the tool also prints the chosen path to stdout so it can be used in scripts and pipes.
How it works
- Scan — the image directory is walked recursively (non-following
symlinks) for supported formats:
png,jpg,jpeg,gif,webp,bmp,tif,tiff,jfif. - Index — each new/changed image is hashed, OCR'd, tagged, and has a thumbnail generated, all in a background thread.
- Cache — results are stored in a SQLite database so re-opening the same folder is instant. Cached entries are reused when a file's size and mtime are unchanged.
- Search — the query is scored against a haystack built from filename +
tags + OCR text using
nucleo-matcher, and results are ranked in parallel. - Copy — on Linux the copy is handed to a tiny background daemon process that keeps serving the clipboard after the UI exits (X11 and Wayland clipboards are owned by a live process); on macOS/Windows the copy is direct.
Cache location
Metadata and thumbnails are cached per-folder, keyed by a hash of the folder path:
$XDG_CACHE_HOME/mfer/when set, otherwise~/.cache/mfer/.
Delete the matching *.sqlite3 file to force a full re-index (or just use
--rebuild).