Implement the hybrid clipboard with deferred cut
⌘X/⌘C/⌘V for cards and lanes per 04-interactions.md § Clipboard: - ClipboardStore stages full folder snapshots eagerly at the gesture into Application Support (at most the current copy; sweep at launch and on each copy purges what the pasteboard no longer references; a copy made before quitting pastes whole after restart) and writes the pasteboard a JSON manifest — every entry embedding its index.md, lane entries their cards' too — plus plain-text titles. - Cut is Finder-style deferred: items dim in place off pendingCut, void on pasteboard takeover (changeCount, no timers), source-board close, or per-item external tombstoning; the first armed paste moves the surviving originals whole (tombstoned interior cards land in the destination's trash), a second paste materializes copies from staging. - Paste anchors by the shared flatten-order rule (NewCardTarget's anchor, extracted); a tombstoned selection never anchors; lane paste reaches the right end and stays enabled on a zero-lane board; paste into the source board is the within-board lane duplicate; copies keep created, take fresh GUIDs, and strip tombstoned cards; trash-sourced copies strip deleted: at materialization; ⌘X is disabled on the trash side. - A degraded paste is loud, never silent: staging gone → the embedded index.md fallback lands content-intact, attachments absent, and a BannerCenter-phrased row names what was lost. - The standard Edit items validate through conditionally-attached onCommand handlers, so AppKit's enablement mirrors the availability predicates; text fields keep their own clipboard while focused. 879 unit tests (68 new). Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -10,7 +10,13 @@ import Foundation
|
||||
/// (`ItemReferenceSet`), so the kind of a selection is always re-derived from the snapshot. Storing
|
||||
/// it would be a second answer to a question the snapshot can always answer, and one that a reload
|
||||
/// could falsify.
|
||||
public enum SelectionKind: Sendable, Equatable {
|
||||
///
|
||||
/// The **one** place a kind is written down is the clipboard manifest, which has no snapshot to
|
||||
/// re-derive it from — "the cards-XOR-lanes selection rule means the clipboard holds cards or lanes,
|
||||
/// never both" (04-interactions.md ▸ Clipboard). Hence `String`-backed and `Codable`: those raw
|
||||
/// spellings are pasteboard API, decoded after a relaunch, and they are the case names so there is
|
||||
/// no second vocabulary to keep in step.
|
||||
public enum SelectionKind: String, Codable, Sendable, Equatable {
|
||||
case card
|
||||
case lane
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user