D20: File operations
Table of Contents
- Status: Decided (2026-09-28)
- Decision: the
trashcrate (5.x) moves files to the system trash; copy, move, delete and the small operations are Kalem's own code onstd::fs, withfiletimefor modification times. They live in thekalem-fscrate, which runs an operation on a background thread with progress, cancellation and a choice for each conflict. - Task: T2.7e.1
1. Candidates
| Option | For | Against |
|---|---|---|
trash + own operations on std::fs |
trash is the maintained cross-platform trash crate (Recycle Bin on Windows, the freedesktop.org trash on Linux, the Finder or NSFileManager on macOS). Own copy and move code can report progress per file, stop between files and ask about each conflict |
Recursive copy, merging into existing folders and moves across devices must be written and tested |
fs_extra |
Recursive copy and move with a progress callback | Conflict handling is a global overwrite or skip flag; cancellation only by returning from the callback; little maintenance |
System tools (cp, mv, trash, PowerShell) |
Nothing to write | Different on every platform, progress and conflicts hard to get, quoting risks |
2. Details
- Trash on macOS.
trashdefaults to asking the Finder through AppleScript, which makes macOS ask the user to let Kalem control the Finder. Kalem uses theNSFileManagermethod instead: no permission prompt and no Finder sound; the Finder's "Put Back" may be missing for these files (a macOS limitation the crate documents). - Copy. Folders recursively, merging into an existing folder; symbolic links copied as links; permissions (by
std::fs::copy) and modification times kept. Copying a file onto itself or a folder into itself is refused before anything is removed. - Move. A rename; across devices (
ErrorKind::CrossesDevices) a copy and a delete. A folder moved onto an existing folder is merged into it. A change of case only (a.txttoA.txt) on a file system that ignores case is a plain rename. - Conflicts. Before an operation starts, the destinations that exist are listed; the user chooses for each one (overwrite, skip, keep both as
name (2).ext) or for all that are left.Operation::choicesholds the choices by destination. - Progress and cancellation.
Job::startruns the operation on its own thread: files and bytes are counted first for a copy, progress is kept per file, and cancelling stops between files. The outcome lists what was done, skipped and failed. - Not yet. Undo of file operations (T2.7e.7) and restoring from the trash: the
trashcrate can list and restore on Linux and Windows, not on macOS.