Skip to content

tui: a preview you can watch, a cancel that says so, and a scope you chose - #40

Merged
ralyodio merged 1 commit into
mainfrom
feat/preview-progress
Sep 13, 2026
Merged

ralyodio merged 1 commit into
mainfrom
feat/preview-progress

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Pressing p on a big local directory showed a bar stuck at 0% over an empty list, and esc ended it with "Transfer stopped by signal SIGINT" in red. Neither was a fault: a dry run transfers no bytes so rsync's percentage is 0 by definition, rsync prints nothing per file when the other side already matches, the panel's clock only advanced when rsync spoke, and esc does send SIGINT.

  • A preview counts files. rsync's to-chk drives the bar (checked ███ 1204/5300 files) with "N changes found so far" beside it, and the clock runs off the wall on a one-second timer from start to stop.
  • Nothing to do is said out loud: "Already in sync, 5300 files checked".
  • Esc is a cancel, in the warning colour, with the note that stopping changed nothing on either side. Detected from the AbortController, so a signal from elsewhere is still a failure.
  • Preview and sync cover the row under the cursor, mirrored to the same relative path in the other pane (directory to same-named directory, file into the directory that holds it, whole pane only when nothing is selected). The title says what ("Scanning src"), --mkpath lets nested targets be created, and after a sync the other pane is re-read in place with every unfolded directory kept open. r uses the same refresh.

The scope is a pure function with its own tests in both directions. The interaction tests run the real rsync against two tmpdir trees: a scoped preview, an "already in sync" preview, a single-file sync with in-place refresh, and an esc landing mid-walk on 4000 files.

Verified: pnpm build, pnpm -r typecheck, pnpm test (636 tests).

🤖 Generated with Claude Code

https://claude.ai/code/session_01DWtLsmAescX4Nb8QiBJd37

…chose

Pressing p on a big local directory showed a bar stuck at 0% over an empty
list for as long as rsync took to walk the tree, and pressing esc ended it
with "Transfer stopped by signal SIGINT" in red. Neither was a fault. A dry
run transfers no bytes, so rsync's percentage is 0 by definition until the
end; and when the other side already matches, rsync prints nothing per file
at all. The panel's clock only advanced when rsync said something. And esc
does send SIGINT: the runner's generic wording for any signal exit was
landing in the panel as a failure.

Four changes:

- A preview counts files. rsync's `to-chk=remaining/total` is what moves
  during a dry run; it now drives the bar (`checked ███ 1204/5300 files`),
  with "N changes found so far" beside it. The clock runs off the wall from
  the moment rsync starts, on a one-second timer, and stops when it stops,
  so a silent walk still visibly takes time rather than looking dead.
- A preview that finds nothing says "Already in sync", with the count of
  files it checked, instead of a full bar over an empty list.
- Esc is reported as a cancel, in the warning colour, with the reassurance
  that stopping changed nothing on either side. It is detected from the
  AbortController, not from rsync's exit, so a signal from anywhere else
  is still a failure.
- Preview and sync cover the row under the cursor, mirrored to the same
  relative path in the other pane: a directory to the directory of the
  same name, a file into the directory that holds it, and the whole pane
  only when nothing is under the cursor. The panel title says what
  ("Scanning src"), and `--mkpath` lets a nested target be created. After
  a sync the other pane is re-read in place, keeping every unfolded
  directory open, so the result appears under the rows that were already
  showing; `r` uses the same refresh.

The scope is a pure function of the two panes and is tested on its own in
both directions. The interaction tests run the real rsync against two
directories under tmpdir: a scoped preview, an "already in sync" preview, a
single-file sync with the in-place refresh, and an esc that lands while a
4000-file dry run is still walking.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWtLsmAescX4Nb8QiBJd37
@ralyodio
ralyodio merged commit a32db2b into main Sep 13, 2026
4 checks passed
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