crabidy/plan/queue-register.md

103 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Plan — queue selection, visual mode, and the register
Executes `architecture/queue-register.md` against
`quality/queue-register.md`. Ordered by dependency. Three commits: **(A)**
the shared mark/visual trait with the library moved onto it, **(B)** queue
marks + the register in `cbd-tui`, **(C)** `cbd-web` parity + docs.
No server work: `Remove` already takes many positions and `Insert` takes a
path list (G25).
## A — Shared mark and visual behaviour (`cbd-tui`)
- [x] **A1 — Fill in `MarkedPane`** in `app/list.rs`: `toggle_visual`,
`toggle_mark`, `toggle_mark_view`, `paint_between`, `selection` — moved
verbatim in behaviour from `library.rs`, with the `markable` gate taken
from the implementor. *Verifies:* G11, G12, G16.
- [x] **A2 — `impl MarkedPane for Library`**, deleting the now-duplicated
inherent methods and keeping `get_selected` as a thin wrapper over
`selection` so existing call sites are untouched. `markable` =
`is_queable`. *Verifies:* the existing library visual-mode suite passes
unchanged (G11, G12).
- [x] **A3 — `carry_marks`** in `app/list.rs`: greedy in-order path match,
drop marks whose track is gone, all-false when nothing matches, tolerant
of a short `old_marked`. *Verifies:* the ten `carry_marks_tests` (G2, G3).
- [x] **A4 — Commit A.** *Merged into commit B:* group A alone leaves
`carry_marks` and `Register` unwired, and committing dead code for the next
commit to use is worse than one larger commit. The extraction is still
proven behaviour-preserving — the library's whole visual-mode suite passes
untouched.
## B — Queue marks and the register (`cbd-tui`)
- [x] **B1 — `impl MarkedPane for Queue`** with `markable` = always, and a
`visual: Option<usize>` field on `Queue`. *Verifies:* G12.
- [x] **B2 — `update_queue` carries marks** through `carry_marks` instead of
rebuilding them as `false`: keep the previous path list and mark flags,
reconcile, apply. *Verifies:* G1, G2.
- [x] **B3 — `Register::set`** (replace the `todo!()`) and an `App.register`
field. *Verifies:* the register suite (G6, G10).
- [x] **B4 — `y` in both panes.** New `Action::LibraryYank` and
`Action::QueueYank`; each takes `selection()`, writes the register, and
clears the marks it consumed. *Verifies:* G5, G14, G15.
- [x] **B5 — `d` in the queue deletes every marked row** (cursor row when
none), writing them to the register first, in one `RemoveTracks` call with
positions from the current list. Replaces the `FIXME`. *Verifies:* G1,
G13, G14, G15.
- [x] **B6 — `c`/`C` fill the register** with the tracks they drop (`C`
everything, `c` everything but the current track). *Verifies:* G4.
- [x] **B7 — `p`/`P` paste the register.** `Action::QueuePaste` /
`QueuePasteBefore` send `InsertTracks(register.paths(), pos)` with `pos` =
cursor + 1 for `p`, cursor for `P`; a no-op on an empty register; the
register survives. `QueueInsertHere`'s old cross-pane behaviour is gone.
*Verifies:* G7, G8, G9.
- [x] **B8 — Queue visual mode in dispatch.** A `queue_move` wrapper
mirroring `library_move`, and the visual auto-leave guard generalized to
whichever pane is in visual mode with its own movement whitelist.
*Verifies:* G11.
- [x] **B9 — Bindings + help.** Queue scope gains `s`, `v`, `V`, `y`, `P`;
library gains `y`; `p`'s description changes. The help modal derives from
`BINDINGS`, so it follows. *Verifies:* G19, G20.
- [x] **B10 — Status feedback.** The pane title shows `— VISUAL` in the
queue as in the library, and a non-empty register is visible somewhere
(title or now-playing line) so paste is not blind. *Verifies:* G22 in
spirit; keeps G9's no-op explicable.
- [x] **B11 — Dispatch tests** for the gates named above. *Verifies:* G1,
G4, G5, G7G9, G13G15.
- [x] **B12 — Commit B** with the whole `cbd-tui` suite, clippy `-D
warnings`, and fmt clean (G24, G26).
## C — `cbd-web` parity and docs
- [x] **C1 — `Register` + `carry_marks` in `cbd-web/src/state.rs`**, same
shape and same test cases as the TUI's. *Verifies:* G17, G18.
- [x] **C2 — Library visual mode** (the piece deferred when `v`/`V` landed
in the TUI): `visual: Option<usize>` on `LibraryPane`, the same anchored
paint, `Action::LibraryVisualMode` on `v`/`V`, auto-leave on non-movement.
*Verifies:* G17.
- [x] **C3 — Queue marks beside the signal.** The web queue owns no list, so
hold `marks: Vec<bool>` plus the path list they were taken against, and
reconcile on each `Queue` update. *Verifies:* G18.
- [x] **C4 — Queue actions:** `QueueToggleMark`, `QueueVisualMode`,
`QueueYank`, `QueuePaste`, `QueuePasteBefore`, plus `d`/`c`/`C` writing the
register — same semantics as the TUI. *Verifies:* G17.
- [x] **C5 — Keymap + `HELP` table** rows for all of the above, keeping the
lockstep test green; clickable equivalents where the web client has them.
*Verifies:* G19.
- [x] **C6 — Verify the web half properly:** clippy for native **and**
`wasm32-unknown-unknown`, `cargo test -p cbd-web`, and a trunk bundle
build. *Verifies:* G26.
- [x] **C7 — Docs.** `docs/src/clients/tui.md` (key table + a register
section), `docs/src/clients/web.md`, `docs/src/queue.md` (what the register
is and is not), and the README usage section. State plainly that `p`
changed meaning. *Verifies:* G21, G22, G23.
- [x] **C8 — `plan/summary.md`** entry, then commit C.
## Deferred (recorded, not dropped)
- Named registers (`"a`) — `Register` is shaped for it; not built.
- A numbered/history register stack, and any cross-client or persistent
register.
- A per-entry queue id in the proto, which would make mark reconciliation
exact instead of a greedy path match.