Moving files
Copy, move, delete, rename, create, touch, and drag and drop. Each operation composes a plan before it runs.
The verbs#
y copies the selection to the other pane, m moves it, d deletes it. When nothing is selected, the verb takes the entry under the cursor. The plan opens; ⏎ enacts; esc dismisses. Pressing a different verb while a plan is up simply rebuilds the plan—stating an intent costs nothing until Enter.
r renames and a creates—both open a name field
right in the panel, and ⏎ does the whole job: commit the name, get
the plan. A trailing / on a created name makes a directory. The
composed commands are guarded—a rename refuses to land on a name that
already exists, so it can never silently replace a neighbor:
rename · move on the same disk (instant) 1 entry · 41.3 GB jodo:/tank/media/camera how: runs locally on the one host involved $ test -e /tank/media/camera/archive-2026 && { echo refused: /tank/media/camera/archive-2026 exists >&2; exit 1; }; mv -- /tank/media/camera/archive-2025 /tank/media/camera/archive-2026 $ test -e /tank/media/camera/archive-2026 && test ! -e /tank/media/camera/archive-2025
mv does not run. The second step
verifies the result.t touches—updates modification times where the entries stand.
It's the simplest plan in the app: one touch --, no gathering,
because there's nothing to measure and nowhere to collide.
What's already there#
Before a copy or move is offered, pālana reads the destination. Anything standing where your files will land is named in the plan, in rust:
will replace photos.db (1.2 MB)—a file will be overwritten,
and the plan tells you how much of it there is. will merge into
archive-2025—a directory of that name exists; the copy folds into it.
won't work—backup is a file here and a folder there—a kind
clash the transfer cannot survive, named before you waste the bytes. And when
the destination can't be read at all: couldn't check the destination —
this may overwrite files there. The plan never claims more certainty
than it has.
Drag and drop#
Dragging is just another way to state an intent—it composes the same plans the verbs do, and nothing enacts until you've read one.
Between panes, a drop plans a copy; hold ⌥ and it plans a move instead. Onto a folder row, the files land inside that folder, not the pane's directory—the row you're pointing at is the destination. From Finder, dropped files are resolved against a real directory listing before anything is planned, rather than reconstructed from the drag event. And a file dragged out of a local pane is a real file to the rest of the Mac: drop it on Mail, a browser upload, anywhere.
If a drop cannot become a plan, pālana states why—for example,
drop refused—same location—and does not compose a command.
Cross-host—the bytes never touch your Mac#
When source and destination are two servers, the plan's transport line tells you the route. The fast path runs rsync on the source host, authenticated by your forwarded agent—the bytes travel jodo → koan and your machine only orchestrates. No forwarding? The plan falls back and says so: a tar stream proxied through this Mac. The plan names the route in either case. The full route vocabulary is on the plan page.
The dangerous half of a cross-host move—deleting the source—is gated:
it appears in the plan marked runs only after the copy above is
verified, and the verification is two visible count commands, one per
host. Watch the gate open →
When both ends are whole ZFS datasets, the plan offers
zfs send | ssh | zfs receive, a block-level transfer that is often
much faster for large moves.
How datasets travel →
Editing a remote file—the round trip#
⏎ on a remote file opens it in its Mac app—and pālana quietly
registers a watch, telling you so in one line: watching config.yaml—a
save offers to send it back. Edit, save, and the panel offers the
return trip as a plan: ⏎ press enter to send it back to
koan:/opt/services/kanyo · esc keeps the edit local.
If you'd rather saves just go back on their own, flip ask before sending saved edits back off in settings—the subtitle says exactly what you're choosing: off: save is save—edits go back to the server on their own. One exception never changes: if the remote file changed since you fetched it, pālana always asks, and names the conflict, before your edit overwrites someone else's.