aboutsummaryrefslogtreecommitdiff

DUET is a two-pane orthodox file manager (Midnight Commander / FileZilla style) built on dirvish/dired. Two dired panes each show any location — local or remote — and single-key actions on the file under point use the opposite pane as the implied target: copy, move, delete, open. The name is recursive: DUET Unifies Endpoint Trees.

Status: pre-alpha. The interaction model and architecture are designed; implementation is staged (below). This repository is the skeleton.

Why DUET

Two dirvish windows already approximate the basics. DUET's durable value is transport reach and a community-extensible backend interface — moving files dired cannot, through one consistent two-pane UX.

The transport quartet

DUET ships four transfer utilities as backends, over TRAMP as the Emacs-native substrate. They do not overlap:

  • rsync — Unix-to-Unix and local. Block-level delta-transfer, zero remote install, faithful Unix metadata. The default for an ssh-reachable host.
  • rclone — cloud and object stores plus the long protocol tail (S3, B2, GDrive, WebDAV, …). The reach rsync lacks.
  • lftp — FTP/FTPS/HTTP with mirroring, parallel transfers, queueing.
  • unison — bidirectional, conflict-aware reconciliation.

One line: rclone is breadth, rsync is depth.

Roadmap

  • Stage 1 — core commander: two-pane UX, connection wizard, rsync + TRAMP transport, copy/move/delete/open, the keybinding scheme.
  • Stage 2 — the backend registry plus rclone and lftp. The differentiator.
  • Stage 3 — directory diff and bidirectional sync (ediff for files; unison / rclone bisync for trees).

Extending DUET

Transports are pluggable. A backend registers via duet-register-backend with:

  • a name;
  • a handles predicate (lambda (src dst) ...) returning a numeric score (lower preferred) or nil if it cannot handle the endpoint pair;
  • a command builder (lambda (src dst opts) ...) returning a process spec;
  • capability flags: :async :resume :bidirectional :progress.

duet--transfer-spec asks every registered backend to score an endpoint pair and picks the lowest-cost handler. The built-in backends register through this same API, so third parties add transports (unison, git-annex, or anything else) without patching core.

License

GPL-3.0-or-later.