Show image copies side by side when comparing #7

Merged
cyplo merged 1 commit from image-side-by-side into main 2026-11-09 13:58:42 +00:00
Owner

The comparison the project is named for, made visual: expanding an image conflict now draws every version in a row - the original on the left, then [a], [b], and so on - each scaled to fit its column. Instead of reading dimension numbers, the user sees which copy to keep.

This replaces the parked work in #1, which predates the event-loop and testing overhaul and whose terminal probe could freeze the keyboard. Two design choices make those problems impossible here:

  • Half-block characters, always. The thumbnails are colored ▀ cells in the same ratatui buffer as everything else, so they work in every terminal - and they flow through the existing clipping, scrolling and snapshot machinery unchanged.
  • The picker never queries the terminal. Picker::from_query_stdio blocks reading stdin; it is deliberately not used, so there is no probe to freeze the keyboard.

Behaviour pinned by fixtures

  • image/compare_three_copies - three versions in a row: original, [a], [b]; one image is wide enough to fill its column edge to edge.
  • image/corrupt_png - the original's PNG header parses (so the group is an image and expands) but its pixels are gone: its column stays blank while the readable copy still shows next to it.
  • image/narrow_five_cols / image/narrow_six_cols - a column narrower than gutter, pixel, gutter cannot show anything, so 5 columns drops the thumbnail block entirely and 6 columns shows the smallest possible thumbnails with labels cut to fit.
  • image/dimensions - the two-copy case, re-accepted with the thumbnails now present.

Checked

  • 70/70 tests pass, clippy clean with -D warnings.
  • Mutating this PR's whole diff against main, as CI will: 28 mutants, 28 caught, 0 missed.
  • Rendered the screens as PNGs and looked at them: the copies sit side by side, the wide image fills its column, the undecodable one leaves its column blank.

Merging this closes the image-comparison item from the plan; #1 can be closed afterwards as superseded.

The comparison the project is named for, made visual: expanding an image conflict now draws **every version in a row** - the original on the left, then `[a]`, `[b]`, and so on - each scaled to fit its column. Instead of reading dimension numbers, the user sees which copy to keep. This replaces the parked work in #1, which predates the event-loop and testing overhaul and whose terminal probe could freeze the keyboard. Two design choices make those problems impossible here: - **Half-block characters, always.** The thumbnails are colored `▀` cells in the same ratatui buffer as everything else, so they work in every terminal - and they flow through the existing clipping, scrolling and snapshot machinery unchanged. - **The picker never queries the terminal.** `Picker::from_query_stdio` blocks reading stdin; it is deliberately not used, so there is no probe to freeze the keyboard. ### Behaviour pinned by fixtures - `image/compare_three_copies` - three versions in a row: original, `[a]`, `[b]`; one image is wide enough to fill its column edge to edge. - `image/corrupt_png` - the original's PNG header parses (so the group is an image and expands) but its pixels are gone: its column stays blank while the readable copy still shows next to it. - `image/narrow_five_cols` / `image/narrow_six_cols` - a column narrower than gutter, pixel, gutter cannot show anything, so 5 columns drops the thumbnail block entirely and 6 columns shows the smallest possible thumbnails with labels cut to fit. - `image/dimensions` - the two-copy case, re-accepted with the thumbnails now present. ### Checked - 70/70 tests pass, clippy clean with `-D warnings`. - Mutating this PR's whole diff against `main`, as CI will: **28 mutants, 28 caught, 0 missed**. - Rendered the screens as PNGs and looked at them: the copies sit side by side, the wide image fills its column, the undecodable one leaves its column blank. Merging this closes the image-comparison item from the plan; #1 can be closed afterwards as superseded.
Show image copies side by side when comparing
All checks were successful
CI / Lint (pull_request) Successful in 32s
CI / Run tests (pull_request) Successful in 41s
CI / Nix checks and package build (pull_request) Successful in 1m4s
CI / Mutation testing (pull_request) Successful in 1m49s
CI / Nix checks and package build (push) Successful in 10s
CI / Lint (push) Successful in 25s
CI / Run tests (push) Successful in 29s
CI / Mutation testing (push) Successful in 7m20s
568c7c92f5
Expanding an image conflict now draws every version in a row - the
original on the left, then [a], [b], and so on - each scaled to fit its
column, so the user can see which copy to keep instead of comparing
dimensions numbers. The thumbnails are half-block characters in the
same buffer as everything else, so they flow through the existing
clipping, scrolling and snapshots unchanged, and the picker never
queries the terminal: the keyboard-freeze from the earlier image
attempt is impossible by construction.

An image that cannot be decoded leaves its column blank while its
readable neighbors still show. A column too narrow for gutter, pixel,
gutter shows no thumbnail block at all; one pixel more shows the
smallest possible ones.

Fixtures pin the three-copy comparison (with a wide image that fills
its column), the blank column for an undecodable image, and both
narrow-terminal behaviors.

Co-Authored-By: GLM 5.3 <noreply@anthropic.com>
cyplo merged commit 568c7c92f5 into main 2026-11-09 13:58:42 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
cyplo/deescalate!7
No description provided.