Skip to content

feat(fm): copy/move between file-manager panes (MC F5/F6, increment B)#28

Merged
iret77 merged 1 commit into
mainfrom
feat/fm-cross-pane
Jul 4, 2026
Merged

feat(fm): copy/move between file-manager panes (MC F5/F6, increment B)#28
iret77 merged 1 commit into
mainfrom
feat/fm-cross-pane

Conversation

@iret77

@iret77 iret77 commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

The defining Midnight Commander operation, on top of #27's keyboard core: F5 copies and F6 moves the selection (or the cursor row) into another file-manager pane — the two-panel workflow the integrated FM was always meant to support.

What lands

  • fm_registry.rs — a data-only singleton of the live FM panes (id, live host:/path label, filesystem namespace, current dir). Each browser publishes its descriptor on every directory change and removes it on close. No view handles are held, so there's no cross-view-borrow or handle-lifecycle risk. Unit-tested upsert / remove / same-fs matching.
  • Copy primitiveSftpBackend::copy_file (+ a default recursive copy_dir): native std::fs copy for the local backend; the live SFTP backend round-trips bytes through a local temp via the proven streaming primitives (SFTP has no server-side copy). Move reuses rename (atomic on one filesystem).
  • F5/F6 behaviour — auto-pick the single other same-namespace pane (the MC two-panel case); 0 or >1 candidates are reported, never guessed. Existing targets are skipped, never silently overwritten; the result (copied / skipped / failed → target) is toasted.
  • Key layout — F6 is now Move (MC parity); rename moves to F2 (kept keyboard-reachable and on the context menu).

Honest scope: same-filesystem copy/move (two local panes, or two panes on the same host). Cross-connection local↔remote transfer (with progress/cancel) is the next increment — it reuses the existing SFTP transfer engine.

Verified: cargo check -p warp 0 errors/0 warnings; 244 sftp + 3 registry + 6 keynav tests green, including 5 new end-to-end tests (copy, move, recursive-dir copy, no-target guard, existing-target skip). No build triggered (per the standing no-build-without-substantial-progress rule).

🤖 Generated with Claude Code

The defining MC operation: F5 copies and F6 moves the selection (or the
cursor row) into another file-manager pane — the two-panel workflow the
integrated FM was always meant to support.

- fm_registry.rs: a data-only singleton of live FM panes (id, live
  host:/path label, filesystem namespace, current dir). Each browser
  publishes its descriptor on every directory change and removes it on
  close — no view handles held, so no cross-view-borrow or handle
  lifecycle risk. Unit-tested upsert/remove/same-fs matching.
- SftpBackend gains copy_file (+ a default recursive copy_dir): native
  std::fs copy for the local backend; the live SFTP backend round-trips
  bytes through a local temp via the proven streaming primitives (SFTP
  has no server-side copy). Move reuses rename (atomic on one fs).
- F5/F6 pick the single other same-namespace pane automatically (the MC
  two-panel case); 0 or >1 candidates are reported, never guessed.
  Existing targets are skipped, never silently overwritten; the result
  (copied / skipped / failed → target) is toasted. Cross-connection
  (local<->remote) transfer stays a later increment.
- F6 is now Move (MC parity); rename moves to F2 (kept keyboard-reachable
  and via the context menu).

Verified: cargo check -p warp 0/0; 244 sftp + 3 registry + 6 keynav
tests green (5 new end-to-end cross-pane copy/move/dir/guard/skip
tests). No build triggered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@iret77 iret77 merged commit ade613c into main Jul 4, 2026
2 checks passed
@iret77 iret77 deleted the feat/fm-cross-pane branch July 4, 2026 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant