Adds an `rclone://<remote>/<path>` scheme backed by the rclone CLI, giving
yazi native browsing of any of rclone's 100+ remotes (S3, GCS, Azure, SFTP,
WebDAV, local, …) without a FUSE mount.
- New SchemeKind::Rclone threaded through the scheme/URL type system,
mirroring Sftp (remote, virtual, Unix-path, byte-encoded path semantics).
- yazi-vfs rclone provider:
- read_dir via `rclone lsjson`
- metadata via `rclone lsjson --stat` (synthesized POSIX mode)
- seekable read-only File streaming `rclone cat --offset`; seek respawns
the child at the new offset. Detects premature EOF and unknown sizes.
- all write ops return Unsupported (read-only for now)
- `remote:/path` targets preserve the leading slash, so filesystem-like
backends (local, sftp) work alongside object stores.
- Config: [services.<name>] type = "rclone", remote = "..."
- Tests:
- tests/rclone_local.rs: hermetic, points an rclone `local` remote at a
temp fixture dir, so it needs no cloud/credentials and skips if `rclone`
isn't installed. Covers list, read, seek, missing-object, and a >8 MiB
parallel multi-chunk copy with position-varying bytes.
- tests/rclone_read.rs: env-driven live tests against a real remote
(ignored by default; paths supplied via env vars, nothing hard-coded).
3.8 KiB
rclone VFS provider for yazi
Browse any of rclone's 100+ remotes — S3, GCS, Azure, Backblaze, SFTP,
WebDAV, Google Drive, … — natively inside yazi,
with no FUSE/NFS mount. It rides on yazi's existing VFS layer (the same
infrastructure behind the built-in SFTP provider) and shells out to the rclone
binary you already have.
Addresses the "Integrate rclone" item on #3395. Read-only for now.
Usage
Point a VFS service at an existing rclone remote in ~/.config/yazi/vfs.toml:
[services.gcs]
type = "rclone"
remote = "gcs" # any remote from `rclone listremotes`
[services.s3]
type = "rclone"
remote = "s3"
# binary = "/opt/homebrew/bin/rclone" # optional: path to rclone
# config_file = "/path/to/rclone.conf" # optional: non-default config
# flags = ["--fast-list"] # optional: extra rclone args
Then browse with a rclone://<service>//<path> URL:
rclone://gcs//my-bucket/some/dir
rclone://s3//my-bucket
rclone://gcs// (empty path) lists the remote's buckets. Everything else is
normal yazi navigation, preview, and copy-out.
What works
- Directory listing —
rclone lsjson - Metadata —
rclone lsjson --stat(size + mtime; POSIX mode is synthesized since object stores have no permissions) - Reading / preview / copy-out — a seekable file handle that streams
rclone cat --offset - Object stores and filesystem backends —
remote:/pathkeeps its leading slash, solocal,sftp, etc. work alongside S3/GCS/…
What doesn't (yet)
- Writes — every mutating op returns
Unsupported. Read-only by design for a first cut; uploads (rclone rcat/copyto) and mutations are a clean follow-up. - Remote search — still disabled globally for remote schemes (per #3395).
How it works
yazi's provider dispatch is a set of static enums, so a new rclone:// scheme
threads a SchemeKind::Rclone variant through the scheme/URL type system —
mostly folded into the existing Sftp arms, since rclone remotes share the same
traits (remote, virtual, Unix-style paths).
The interesting part is the file handle. rclone has no persistent open-file
concept, so Provider::File (which must be AsyncRead + AsyncSeek) is
implemented by streaming rclone cat from the current position; a seek kills
the child process and the next read respawns rclone cat --offset <new>. This
is enough for yazi's previewer and for its parallel chunked copier (which opens
several handles and seeks each to its 8 MiB slice).
Testing
Two layers, no credentials required to run CI:
tests/rclone_local.rs— hermetic. Points an rclonelocalremote at a generated temp directory, solsjson/catrun against the filesystem. Needs only therclonebinary; skips itself if rclone isn't installed (so CI without rclone stays green). Covers listing, read, seek, missing-object, and a8 MiB parallel multi-chunk copy with position-varying bytes so any offset slip is caught.
tests/rclone_read.rs— live,#[ignore]d. Runs against a real remote you point it at via env vars (YAZI_RCLONE_TEST_SMALL/_BIG/_DIR) — nothing is hard-coded.
Verified end-to-end against live GCS and S3 buckets: byte-exact reads, mid-file seeks, and both simple and progressive (parallel multi-chunk) copy-out.
Notes / open questions for upstream
- CLI vs daemon. This spawns an
rcloneprocess per operation — simple, no lifecycle to manage. A long-livedrclone rcd(remote-control daemon) would cut per-op latency and enable connection pooling like the SFTP provider does. Happy to go either way. - Read-only scope. Matches the earlier S3 PR (#3843). Writes can follow once the direction is settled.