pālana

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 · the plan ⏎ enter runs
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
The guard is part of the command. If the new name already exists, the plan refuses and 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.