Wire native undo into menus, toolbar, and command validation
The command surface was already almost entirely platform machinery — this card proves it and pins it. Headless probes established that NSWindow.validateMenuItem answers enablement AND rewrites the row title from the delegate-supplied manager, so 'Undo Move 3 Cards' flows step phrase to Edit menu with no code of ours; under the lock the rows dim and keep their names, the correct reading of the-stack-survives. The toolbar twins validate through validateUserInterfaceItem, which never touches labels — 03's static-label exception proven rather than asserted — and their specs' enablement abstention is pinned so nobody later adds a second, disagreeing answer. The one link a headless run cannot close is the nil-target key-window resolution itself: standard responder-chain behavior with none of our code in it, left as the manual check. Base-edition 'disabled without undo' scaffolding is reworded away — every base board has undo now. New suites cover the trash's two doors (delete-then-undo byte-identical to Put Back's effect), position-preserving restore of a middle card, and the capstone: five gestures forward, five presses back to the origin board, five forward again, the menu phrase asserted after every press. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -44,6 +44,8 @@ Lanework is in early development. This list tracks what has actually shipped and
|
||||
|
||||
- **Customizable toolbars** — both windows carry a real macOS toolbar: right-click ▸ Customize Toolbar…, drag to rearrange, the system overflow, and the Icon and Text / Icon Only / Text Only display options, with your arrangement remembered across launches. They are pure enhancement — every item is a menu command with a shortcut, so removing all of them costs you nothing but a click. The board ships with the search field alone, trailing, and offers New Card, New Lane, Undo, Redo and Show Trash in the palette (Undo and Redo validate exactly as the Edit menu's rows do, and keep static labels because the menu's titles rewrite themselves); the board popover deliberately has no item, since the window-title chevron is its home. Take the search field out and ⌘F still summons search — the field appears in a strip just under the title bar and stays until the search clears, keeping the keyboard while you type. The card window ships Edit Body · Raw Source · Add Attachment, the first two as toggles showing their on-state, with Edit Body disabling while raw source is up and Add Attachment live in every mode.
|
||||
|
||||
- **Undo** — ⌘Z and ⇧⌘Z are native macOS undo, per board: one stack owned by the board's session and shared by every window over it, so a card window's ⌘Z crosses the same step the board window's does, and another board's never does. Every app-mediated mutation registers an inverse at the write boundary — create, move, reorder, rename, restyle, resize, delete, Put Back, and an Edit session's whole run of saves — one gesture to one step, named in the app's own vocabulary so the Edit menu reads "Undo Move 3 Cards" and the toolbar's twins light up and dim with it. Undoing is a real write, never an in-memory revert: it goes through the same atomic writer, echoes back through the watcher, and refreshes every window. Because the app is not the only writer, each step re-checks its target the moment you press ⌘Z — field by field, against what its own write left — and a step the disk has moved past is **skipped rather than applied**, with a quiet row saying which item changed outside Lanework, while ⌘Z falls through to the next step; a step that merely failed to write (a full disk, an unplugged volume) stays put to be retried. Permanent deletion and the duplicate-id repair are deliberately outside it — the confirmation is the safety — attachment add and remove register nothing in v1, and foreign edits never join the stack. The read-only lock disables Undo and Redo with every other mutating command and gives them back, stack intact, when it clears. The stack lives with the session and dies at close, standard macOS behaviour. Both editions ship it: base runs the native stack, and Lanework Pro binds git behind the same seam without changing a keystroke.
|
||||
|
||||
## Development
|
||||
|
||||
The Xcode project is generated — `project.yml` is the source of truth, not the `.xcodeproj`:
|
||||
|
||||
Reference in New Issue
Block a user