sucher
A fast terminal viewer for the files that are awkward to open in a browser — markdown, spreadsheets, data files (Parquet, JSONL, SQLite, DuckDB), PDF, images, SVG, video, Word/PowerPoint/Keynote, EPUB e-books, archives, and raw binary — behind one tiny command:
Sucher is German for the camera viewfinder — the little window you look through to frame a shot. This one frames files: it picks a viewer by file extension and renders it in place, using your terminal's graphics protocol for real pixels where one is available.
Demo

| Directory browser | Markdown & docs | Video & images |
|---|---|---|
![]() |
![]() |
![]() |
Highlights
- One launcher, many formats — dispatch by extension, sensible TUI per type.
- Directory browser — point
sat a folder (or run it bare) for a fast, two-pane navigator: live preview pane, fuzzy filter, andEnteropens the selection in its viewer, then drops you back where you were. - Recursive search (
S) — find files anywhere below the current directory, streamed live as they're found (ripgrep's own walker,.gitignore-aware). The same smart query as the filter, pluscontent:to grep inside files — and every hit renders in the preview pane as the actual framed file (the PDF page, the image, the spreadsheet grid), not a grey line of text. - File operations that never destroy. Mark across folders with
Space, then copy/cut/paste (yXp), rename (r), create (a), delete (D). Every batch shows its plan before it runs: what lands where, what got a(2)suffix to dodge a collision, what has vanished since you marked it. Nothing is overwritten silently, and nothing is ever permanently deleted: delete means the system trash, and so does anything an overwrite displaces or an undo takes back.Uundoes the last operation. Large copies run in the background with live progress, so the browser stays usable while they go. - Handles huge files — a 240 MB / 800k-row spreadsheet opens in ~160 ms and stays scrollable, because sheets stream in on a background thread instead of being loaded whole.
- Queryable data files — Parquet, JSONL, SQLite, and DuckDB open in the grid:
each database table becomes a tab, columns keep their real names and types
(ISO dates, not serial numbers), and a
:SQL prompt — powered by an embedded DuckDB — turns any of them into a live query over the file. It's lazy and uncapped, so a billion-row Parquet opens instantly and scrolls to the end, and fully offline — reading a data file never touches the network. - Real graphics — images, rasterised SVGs, PDF pages, video frames, and
Keynote previews render as actual pixels via the kitty / iTerm2 / sixel
protocols (with a Unicode half-block fallback), through
ratatui-image. - Real typography in pipe mode —
s --plain doc.mdemits the kitty text-sizing protocol so headings render larger on supporting terminals; detected at runtime, with graceful fallback. - Responsive — event-driven redraw (no idle CPU churn) and background work for the expensive bits.
Supported formats
| Category | Extensions | Backend |
|---|---|---|
| Markdown | .md .markdown .mdx |
pulldown-cmark |
| HTML | .html .htm .xhtml |
html5ever DOM walk → markdown renderer |
| Text / source | code, .txt .log, config files, extension-less UTF-8 text |
syntax-highlighted text viewer (no soft-wrap; pan + search) |
| Spreadsheet | .xlsx, .xlsm |
streaming reader (zip + quick-xml) on a worker thread |
| Spreadsheet | .xls, .ods, .xlsb, .csv, .tsv |
calamine (eager); csv/tsv parsed into the grid |
| Data — columnar | .parquet .pq |
embedded DuckDB (read_parquet) |
| Data — line JSON | .jsonl .ndjson |
DuckDB (read_json_auto) |
| Data — SQLite | .sqlite .sqlite3 .db .db3 |
rusqlite bundled libsqlite (read-only); each table a sheet |
| Data — DuckDB | .duckdb .ddb |
DuckDB ATTACH (read-only); each table a sheet |
.pdf |
pdfium (Chrome's engine) → graphics, poppler pdftocairo fallback |
|
| Image | .png .jpg .jpeg .gif .webp .bmp .tiff .ico |
image → graphics |
| SVG | .svg |
resvg rasteriser → picture above scrolling source |
| Video | .mp4 .mov .mkv .webm .avi .m4v |
streaming ffmpeg pipe → graphics |
| Word | .docx |
unzip + streaming XML → markdown renderer |
| Presentation | .pptx |
unzip + streaming XML (slide text) → markdown renderer |
| E-book | .epub |
unzip + spine order → HTML → markdown renderer |
| Notebook | .ipynb |
JSON cells → markdown + code + outputs (images to gallery) |
| Keynote | .key |
embedded QuickLook preview image → graphics |
| Archive | .zip .tar .tar.gz .tgz .gz |
navigable table of contents (folders + path + size); no extraction |
| Binary | unrecognized non-text files | scrolling canonical hexdump (offset │ hex │ ASCII) |
| Directory | any folder | two-pane file browser (list + live preview) |
Comma/tab-separated values (.csv .tsv) open in the spreadsheet grid.
Legacy office binaries (.doc .rtf .odt .ppt) and audio have no viewer:
opening one shows a one-line size/modified summary rather than launching a viewer
or dumping bytes. Other archive types (.7z .rar .xz .bz2 .zst) are
recognized but have no lister; extract them with a shell tool.
When stdout is not a TTY (piped), sucher prints a sensible text dump instead of
launching the TUI (pdftotext for PDF, TSV for sheets and data files, metadata for video,
styled text for markdown/html/docx/pptx/epub/ipynb, faithful bytes for text/source, raw XML for
SVG, a canonical hexdump for binary, a size⇥path table for archives, a plain
listing for directories).
Data files & SQL
The files most technical users live in — Parquet, newline-delimited JSON,
SQLite and DuckDB databases — open in the same grid as spreadsheets, backed by
two native, statically-bundled engines behind one interface: an embedded
DuckDB reads Parquet/JSONL/DuckDB, and rusqlite's bundled libsqlite reads
SQLite. Real column names sit in the header (not A/B/C),
DuckDB's canonical text gives correct ISO dates and timestamps (NULL renders
blank), and a database opens read-only with each table as its own sheet —
Tab (or [ / ]) cycles them, and the SQL prompt can join across them.
Sample files ship in samples/ so you can try it straight away:
Press : in the grid for an interactive SQL prompt that runs over the
current file; the result replaces the view (schema, rows, and / search all
follow it). For a single-file source, FROM the file's stem; for a database,
FROM any table or join across them:
: SELECT region, sum(revenue) AS total
FROM sales GROUP BY region ORDER BY total DESC
A live query shows truncated in the status bar. A parse/bind error stays in the prompt with your text — and the previous view — intact; empty input reverts to the base table; switching tabs drops the query.
It's lazy and uncapped. The grid windows rows on demand (LIMIT/OFFSET
plus a prefetch cache) and reads the schema from DESCRIBE, which doesn't
execute the query — so a file opens instantly regardless of size and scrolls to
the end with no row cap, unlike the streaming .xlsx/CSV backends. And it's
fully offline: both engines are compiled in statically and DuckDB has
extension autoinstall/autoload disabled, so reading a data file never reaches for
the network, in keeping with
sucher's local-viewer identity.
Data files sit behind the default-on data Cargo feature, so
cargo install sucher includes them out of the box. DuckDB is compiled from
vendored source and statically bundled — self-contained, with no build-time
download and no runtime network — which puts the release binary at ~65 MB.
If you don't need it, cargo install --no-default-features builds the lean
~26 MB binary without DuckDB (Parquet then falls back to the hexdump and JSONL
to the text viewer).
Install
Requires a recent Rust toolchain.
# Quickest — installs the `sucher` binary into ~/.cargo/bin:
Or clone for the short s alias and make targets:
make install puts the binary in ~/.cargo/bin and creates a short s symlink
next to it. (make uninstall removes both.)
The fast PDF path is self-contained: the build fetches the pinned,
checksum-verified libpdfium for your platform and embeds it in the binary
(materialised to a cache dir on first use), so cargo install sucher gets it
with no extra steps. Offline or sandboxed builds skip the fetch and fall back to
poppler; pre-place the library at vendor/pdfium/<lib> or point
SUCHER_PDFIUM_LIB at one to build the fast path offline, or set
SUCHER_PDFIUM_NO_EMBED=1 to opt out.
Optional runtime dependencies
These are only needed for the formats that shell out to them:
| For | Needs | macOS |
|---|---|---|
| PDF (fallback) | poppler (pdftocairo, pdfinfo, pdftotext) |
brew install poppler |
| Video | ffmpeg, ffprobe |
brew install ffmpeg |
The fast PDF path uses libpdfium, embedded in the binary at build time (no
install step); poppler remains the fallback and still powers pdfinfo/pdftotext.
For pixel-perfect images / PDF / video, use a terminal with a graphics protocol — kitty, ghostty, WezTerm, iTerm2, or any sixel-capable terminal. Without one, sucher falls back to Unicode half-blocks.
Themes, icons & layout
The browser's palette, file icons, column layout, and git gutter are configurable. Resolution order, highest first: CLI flag → environment variable → config file → default.
SUCHER_THEME=gruvbox-dark SUCHER_ICONS=none
Config file at $XDG_CONFIG_HOME/sucher/config.toml (else
~/.config/sucher/config.toml); a missing or malformed file is ignored, never
fatal:
= "catppuccin-mocha" # or "auto" | built-in name (default: sucher-dark)
= "nerd" # "unicode" (default) | "nerd" | "none"
= "auto" # "auto" (default) | "miller" | "double"
= true # show the git status gutter (default: true)
= true # click rows/breadcrumb, wheel-scroll (default: true)
= true # folder fade + full-view zoom (default: true)
[] # optional per-key hex overrides, applied last
= "#7dd3fc"
= "#26324a"
- Themes — built-ins:
sucher-dark(the default),sucher-light,catppuccin-mocha,gruvbox-dark,tokyo-night.theme = "auto"picks a light or dark default from the terminal background (COLORFGBG/ OSC 11, falling back to dark). - Icons —
unicode(geometric glyphs, renders on any font — the default),nerd(per-extension Nerd Font glyphs with per-language tints — requires a patched Nerd Font; not auto-detected, so opt in), ornone(no icon column). - Layout —
autoshows three columns (parent · current · preview, the ranger-style Miller layout) on wide terminals (≥ 100 cols) and collapses to two (current · preview) when narrow;millerforces three,doubleforces two. Toggle live withM. - Git gutter — in a git working tree, each entry shows a colored status
marker (
●modified ·+added ·?untracked ·✗deleted ·»renamed ·!conflict); directories aggregate their descendants' changes. Absent outside a repo or withgit = false. - Repo HEAD readout — inside a repo, the breadcrumb row shows the current
branch (or detached commit) right-aligned, with ahead/behind arrows vs the
upstream and a
●dot when the tree is dirty:⎇ main ↑2 ↓1 ●. Follows the samegittoggle as the gutter. - Mouse — click a file row to select it, click the highlighted row to open
it (or enter a folder); click a breadcrumb segment to jump there; in the
three-column layout click the left pane to go up; scroll the wheel to move the
selection. Capturing the mouse disables the terminal's own click-drag text
selection inside sucher (Shift/Option-drag still bypasses it in most
terminals); set
mouse = falseto keep native selection. - Animations — entering/leaving a folder fades the new listing in; opening a
file in the full-screen image viewer zooms it up (and back down on close). Both
are time-based (~120–150 ms), interruptible by any keypress, and disabled with
animate = false. The folder fade is a cheap cell redraw that presents at the display's refresh rate; the image zoom re-encodes the picture each frame, so it runs at whatever the graphics pipeline sustains (constant duration either way).SUCHER_ANIM_STATS=1prints each animation's achieved frame rate on exit.
Usage & keys
|
Directory — j/k ↑/↓ move · d/u half-page · g/G top/bottom ·
Enter/l/→ open file or enter folder · h/←/Backspace parent ·
x open in native app · / smart filter · S recursive search ·
o cycle sort (name/size/modified/ext) ·
O reverse sort · . toggle dotfiles · M two/three-column layout ·
t size/modified column · ? key overlay · q quit.
Select and act (see File operations below)
Space mark/unmark then move down · V invert marks · Ctrl-a mark all ·
y/X copy/cut · p paste here · r rename · a create (trailing / makes
a folder) · D move to trash · U undo · Y yank absolute path(s) ·
Esc backs out one layer at a time (cancel the run, then the clipboard, then
the marks, then quit).
Press ? for a
which-key overlay of every binding (it also shows the current sort). Click a
breadcrumb segment to jump there;
the wheel scrolls the list. The right pane renders a live
preview of the selection: images (animated GIFs loop in place), SVGs, PDFs
(page 1), video posters, and Keynote previews as real pixels,
markdown/docx/pptx/epub/ipynb with full typography, a
grid preview for spreadsheets (including csv/tsv), a table of contents for
archives, a hexdump for binary, a child listing for folders, and the head
of the file for text/code. Previews are cached as you move.
The / filter mixes free-text fuzzy matching with structured predicates, e.g.
report kind:pdf size:>1mb modified:<7d ext:rs. Plain words fuzzy-match the
name; four key:value predicates narrow by metadata:
kind:—pdf,image,video,audio,sheet,doc,markdown,code,archive,folder,binary(and aliases).ext:— a file extension, e.g.ext:rs.size:—>1mb,<=100kb,500(unitsb/kb/mb/gb/tb; bare = at least).modified:— file age, e.g.<7d,>2w(unitss/m/h/d/w/mo/y).
Outside the filter, just type a name to jump to the first matching entry
(type-to-select); a brief pause or Esc ends the jump, and the vim motion keys
keep working whenever you're not mid-type.
Search (S) is the filter's recursive sibling: instead of narrowing the
current listing, it walks the whole tree from here downward and streams matches
in live as they're found, kept sorted (by the current sort — relative path
by default, so results group by folder) as they arrive rather than in the
walker's nondeterministic finish order. Type to refine; ↑/↓ (and PgUp/PgDn) move
through results, Enter opens the selected hit (or jumps into it if it's a
folder), Esc returns to browsing. It takes the same query language as the
filter — every kind: / ext: / size: / modified: predicate works — plus
one more that only makes sense across files:
content:(aliasescontains:/grep:) — a literal substring to find inside files, e.g.content:TODO ext:rs. Matching is smart-case (case-insensitive unless you type an uppercase letter) and each hit shows the matchingline: text. Powered by ripgrep's own line searcher, so binary files are skipped and huge files stream rather than load.
The walk uses ripgrep's parallel directory walker: it honours .gitignore, skips
dotfiles unless . toggled them on, and caps at 5000 hits (surfaced in the
status line). Because every result flows through the same preview pane, a hit is
shown as the real rendered file — the differentiator over fd/rg/fzf.
File operations. sucher stays a viewfinder: it changes where files are, never what they contain. There is no editing, no archive extraction, and no writing to a spreadsheet or database. What it does do is the shell around files: mark, copy, move, rename, create, delete.
Space marks the entry under the cursor and steps down, so holding it marks a
run. The mark set is global: it survives walking into other folders, which is
what makes "gather five files from three directories, then act once" the point of
the feature rather than a slower cursor. V inverts the current view, Ctrl-a
marks all of it. With nothing marked, every verb acts on the entry under the
cursor instead, so the keys work before you have learned marking at all.
y copies and X cuts to a clipboard that survives navigation; p pastes into
the directory you are standing in. r renames, opening pre-filled with the
cursor sitting between the name and the extension, so you can extend the name,
backspace over it, or move around it with the arrow keys without ever putting
.txt at risk. a creates, and a trailing / makes a folder instead of a file.
Every batch shows its plan before anything happens: how many items and bytes,
where each one lands, which names got a (2) suffix to dodge a collision, and
which marked paths have vanished since you marked them. Enter authorises, Esc
cancels, and o toggles overwriting, which re-plans the batch and shows the
count it would replace in red. Collisions are suffixed by default and overwriting
is never the automatic answer.
Nothing is ever permanently deleted. D moves to the system trash, and there
is no permanent-delete binding at all. The rule is total rather than a property
of one key: an overwrite trashes whatever it displaces before writing, a move
across devices trashes the original after the copy lands, and undoing a copy
trashes what sucher created. Where no trash is available (some remote mounts) the
operation fails and says so rather than quietly falling back to rm.
U undoes the last operation, replaying the inverses of the steps that actually
happened, so a partly failed run undoes exactly the part that succeeded. A
trashing is the exception: the system trash is where those come back from, and
the report says so instead of pretending. Large operations run in the background
with live progress and can be cancelled with Esc; sucher refuses to quit while
one is still running rather than exiting with the work half done.
Y yanks the selected absolute path(s) to the system clipboard using OSC 52, so
it works over ssh with no helper binary. Delivery is up to the terminal (tmux
needs set -g set-clipboard on), and the status line says so rather than
claiming more than it knows.
Markdown — j/k ↑/↓ scroll · d/u half-page · g/G top/bottom ·
t table of contents · / search (n/N next/prev) · l link picker ·
i image gallery (for docx/pptx/epub/ipynb embedded media; n/p cycle) ·
x open in native app · ? help · q quit.
Text / source — j/k ↑/↓ scroll · d/u half-page · g/G
top/bottom · h/l pan long lines · / search (n/N next/prev) ·
x open in native app · q quit.
Spreadsheet — h/j/k/l or arrows move cell · PgUp/PgDn ·
g/G top/bottom · Tab / [ ] switch sheet · / search all cells
(n/N cycle) · x open in native app · q quit. Status bar shows the cell
ref, value, and load progress.
PDF — j/k, ←/→, or space page · g/G first/last ·
x open in native app · q quit. Rendered with pdfium (Chrome's engine)
when its library is present — a scanned page opens in ~30 ms instead of the
several seconds poppler's software rasteriser takes — and falls back to poppler
otherwise. Pages render off-thread with the neighbours prefetched, so stepping
through is near-instant; visited pages stay cached. libpdfium is embedded in
the binary at build time, so the fast path works out of the box; set
SUCHER_PDFIUM_LIB to override with a specific copy.
Image — x open in native app · q quit.
SVG — the rasterised picture fills the top pane; the XML source scrolls
below it with j/k ↑/↓ · g/G top/bottom · x open in native app ·
q quit.
Video — auto-plays on open · space play/pause · ←/→ ±5 s ·
↑/↓ ±30 s · ,/. frame step · g/G start/end · x open in native app ·
q quit. No audio.
Archive — j/k ↑/↓ move · d/u half-page · g/G top/bottom ·
Enter/l open folder · h/Backspace parent · x open in native app ·
q quit. A read-only, navigable table of contents (path + size) with a
breadcrumb; sucher lists and lets you browse folders, but never extracts.
Binary (hex) — j/k ↑/↓ scroll · d/u page · g/G top/end ·
x open in native app · q quit.
Remote filesystems (S3, GCS, …)
sucher is a local viewfinder: it works on any path the operating system
gives it. So the clean way to browse a cloud bucket is to make it look like a
path — mount it, then point s at the mount. No sucher-specific setup, no
credentials for sucher to hold, and everything works over it unchanged: the
browser, every viewer, and the recursive S search.
# Amazon S3 — AWS's official FUSE mount (or `rclone`, below)
# Google Cloud Storage
# Anything rclone supports (S3, GCS, Azure, Backblaze, SFTP, …)
Because the bytes come over the network, expect the obvious: previews and
graphics fetch on demand (a cache helps — e.g. rclone's --vfs-cache-mode full), and a content: search downloads each candidate object, so scope it
with ext:/size: on large buckets. Name/kind:/ext:/size:/modified:
search only reads directory metadata and stays cheap.
Native cloud sourcing inside sucher (its own S3/GCS client, no mount) was considered and deliberately left out for now — it would trade the zero-config local-viewer identity for an SDK/auth/async surface, and mounts already cover the use case. See ADR 0007 for the search design that a native remote source would have to extend.
How it works
main.rs dispatch by format; TTY → TUI, pipe → text dump
format.rs single classification registry (one source of truth)
dir.rs directory browser (list + live preview), opens files via main
search.rs recursive/streaming/content-aware search engine (ignore + grep)
marks.rs the browser's global multi-select set (pure, no filesystem)
fileop/ file operations: collect (bounded walk) -> plan (pure) -> execute
lineedit.rs single-line buffer with a cursor, for the rename/create prompt
markdown.rs parse → logical lines + TOC + links; width-aware wrap/layout
tui.rs markdown TUI (scroll / TOC / search / links)
text.rs source/plain-text TUI (highlight, no wrap, pan + search)
plain.rs one-shot markdown renderer (kitty text-sizing in pipe mode)
sheet.rs grid UI over a `Book` (eager calamine, streaming xlsx, or lazy data)
xlsx.rs background streaming .xlsx reader (zip + quick-xml), capped
data.rs data files via DuckDB (Parquet/JSONL/DuckDB) + rusqlite (SQLite) + SQL prompt
pdf.rs pdfium page raster (poppler fallback) + prefetch/cache, sized to the display
pdfium.rs runtime-loaded pdfium service thread (one parse, resident doc)
imgview.rs image viewer
svg.rs resvg rasteriser + split image/source viewer
video.rs streaming ffmpeg pipe + background decoder, paced w/ frame-drop
html.rs .html → markdown via html5ever DOM walk (reuses the renderer)
docx.rs .docx → markdown (reuses the markdown renderer)
pptx.rs .pptx slide text → markdown (reuses the markdown renderer)
epub.rs .epub spine → HTML → markdown (reuses html.rs + the renderer)
ipynb.rs .ipynb JSON cells → markdown + code + outputs (reuses the renderer)
keynote.rs .key → embedded QuickLook preview image
archive.rs zip/tar/gz table-of-contents lister
hex.rs canonical hexdump viewer for binary files
media.rs shared graphics pane (ratatui-image protocol probe + render)
Design notes:
- One classifier.
format.rsowns a singleFormatregistry that answers both which viewer opens a file and how the browser colours / labels it, so the two can never drift. Classification is a pure, unit-tested function (extension first; a byte head disambiguates only unknown / extension-less files). Only legacy office binaries (.doc/.rtf/.odt/.ppt) and audio lack a viewer: they show a one-line size/modified summary instead of opening, and their bytes are never fed to a text or markdown renderer. - Spreadsheets stream. Only the current sheet is held in memory; rows are parsed incrementally on a worker thread and the grid reads them live, so opening is independent of total file size. Switching sheets frees the previous one. A row cap bounds pathological files.
- Three Book backends. The grid's
Bookseam now spans three shapes — eager (MemBook, calamine/CSV), capped-streaming (StreamBook,.xlsx), and lazy-data (DataBook,data.rs) — each the right fit for its source.DataBookitself holds two native engines behind one interface: DuckDB (Parquet/JSONL/ DuckDB) and rusqlite (SQLite), chosen so every format is read by the engine that owns it and stays offline (both statically compiled; DuckDB extension autoinstall/autoload off). Data reads are lazy & uncapped (window on demand, schema without executing). The:SQL prompt is the grid's first capability that varies by backend — a method onBook, not a new viewer (ADR 0016). - File operations decide before they act. The hard part of a file manager is
the decision matrix, not the syscall: name collisions, a destination nested
inside its own source, the user standing in the directory being moved. So
collectestablishes the facts (one bounded walk, symlinks recorded and never followed),planis a pure function from those facts to either a fully resolved plan or a named refusal, andexecutereplays a decided list on a background thread with nothing left to choose. The whole matrix is unit-tested with no temp directory, and the confirm overlay can show the exact outcome before a byte moves.trash::deleteandfs::renameeach sit behind a single private seam, which is what makes "sucher never permanently deletes" a property of the engine rather than a rule every caller has to remember. - PDF renders to display size (
pdftocairo -scale-to-x <terminal px>) rather than a fixed DPI, and caches rendered pages. - Video drives a single long-lived
ffmpegprocess emitting raw frames; a decoder thread paces to real time and keeps only the latest frame, so a slow terminal drops frames instead of falling behind. Effective frame rate is bounded by how fast the terminal can transmit images, not by decoding.
Development
A large-workbook benchmark is included but ignored by default:
SUCHER_BIG=/path/to/big.xlsx
Limitations
- DOCX/PPTX keep text structure (headings, bold/italic, lists, tables; slide
text as bullets). Embedded images are viewable in an image gallery (
i) but not shown inline; page layout and exact styling are dropped. - Keynote shows the embedded QuickLook preview (cover / first slide), not per-slide content — the IWA protobuf body isn't decoded.
- SVG rasterises shapes, gradients, and paths;
<text>needs system fonts, which the headless rasteriser doesn't load, so text elements may not appear. - Archives are listed and folder-navigable, but never extracted: you can browse into directories, though individual entries can't be opened or unpacked.
- Spreadsheet dates show as serial numbers (style table isn't read); the streaming reader caps very large sheets. (Data files don't have this wart — DuckDB renders dates as ISO text.)
- Data files are read-only: databases are attached
READ_ONLY, and there's no writing or editing. A.dbthat isn't actually SQLite errors on open rather than falling back. Arrow/Feather files aren't supported — DuckDB's Arrow file reader isn't in the bundled build and would need a network extension, so it's deliberately excluded (Parquet covers the columnar need). Afind/search over a data file follows the query's scan order, not a stable row order. - The release binary is ~65 MB because DuckDB is compiled in and statically
bundled; build the lean ~26 MB binary with
cargo install --no-default-features(dropping thedatafeature and Parquet/JSONL/SQLite/DuckDB support). - File operations act on whole paths only. There is no editing, no archive
extraction, no writing to a spreadsheet or database, no permission changes, no
bulk rename through an editor, and no symlink creation on paste. Operations are
browse-mode only: recursive search is a text surface where every printable key
belongs to the query, so press
Enterinto a hit's folder and act there. - There is no permanent delete, by design. On a filesystem with no trash
(some remote mounts)
Dfails and says so rather than falling back torm. Restoring a trashed file is the system trash's job, not sucher's, soUsays where to look instead of pretending it can bring one back. - One operation runs at a time; a second is refused rather than queued. A single operation is capped at 50,000 entries and 64 levels of depth, and a batch past either is refused whole before anything is mutated rather than copied halfway.
- A cross-device move (any FUSE mount) is a copy followed by trashing the original, so undoing one leaves a recoverable duplicate in the system trash alongside the restored tree.
Yuses OSC 52, which is fire-and-forget: sucher can confirm it sent the sequence, never that the clipboard took it. tmux needsset -g set-clipboard on.- Video has no audio, and terminal frame rate is capped by image transmission.
- Inside the full-screen TUI, markdown headings use color/bold (not the
text-sizing protocol — that applies to
--plain/ pipe output). - In the directory browser, previews render synchronously as you move the
selection, so a PDF or video poster adds a brief raster pause on first visit
(cached afterward). Video shows a poster frame, not playback — press
Enterto open the full player.
License
MIT — see LICENSE.


