diff --git a/IMPLEMENTATION.md b/IMPLEMENTATION.md index adf577b..71ddab0 100644 --- a/IMPLEMENTATION.md +++ b/IMPLEMENTATION.md @@ -545,12 +545,109 @@ Phase 40.1 complete with all issues resolved: - ✅ Red flash on invalid movement - ✅ Clean, production-ready code +--- + +## Iteration 7: Phase 40.2 - Complete Vim Motion System + +**Date**: 2025-01-22 + +### Goals +- Implement anchor moves (0, ^, $, gg, G) +- Add count prefixes (5j, 10l, etc.) +- Add repeat motion (.) +- Handle the "0 caveat" properly + +### Tasks Completed + +#### 1. Created useVimMotions Hook +Complete vim motion processor with state management: +- Count buffer tracking (countRef) +- Last motion tracking for repeat +- Pending g state for gg sequence + +#### 2. Implemented Anchor Moves +**Horizontal (Row-based):** +- `0` or `^` → Start of row (col 0) +- `$` → End of row (col 8) + +**Vertical (Column-based):** +- `gg` → Top of column (row 0) +- `G` → Bottom of column (row 8) + +#### 3. Count Prefix Support +- Works with all directional moves: h, j, k, l +- Examples: `5j`, `10l`, `3k`, `2h` +- Bounded to grid limits (0-8) +- Red flash on invalid moves + +#### 4. Repeat Motion +- `.` → Repeats last motion with same count +- Tracks motion direction and step count +- Works with both direct moves and counted moves + +#### 5. Solved the "0 Caveat" +**Problem**: 0 needs to work as both anchor AND count digit +- `0` alone → anchor to start +- `10j` → count of 10 + +**Solution** (from vim-maze): +```typescript +if (key === '0' && countRef.current === '') { + return { type: 'anchor', data: 'start' }; // Anchor +} +countRef.current += key; // Count digit +``` + +**Logic**: Check if count buffer is empty +- Empty → 0 is anchor +- Not empty → 0 is count digit + +#### 6. Fixed gg Two-Key Sequence +**Bug**: Single `g` was triggering immediately + +**Solution**: Added `pendingGRef` state +- First `g` → Set flag, wait for second key +- Second `g` → Trigger "top" anchor +- Any other key → Clear flag, no action + +### Technical Implementation + +**processKey Return Types:** +```typescript +{ type: 'move', data: Motion } // h/j/k/l with count +{ type: 'anchor', data: string } // 0/^/$/gg/G +{ type: 'repeat', data: Motion } // . +{ type: 'count', data: string } // 0-9 +null // Ignored key or pending state +``` + +**Motion Tracking:** +```typescript +type Motion = { dr: number; dc: number; steps: number }; +// Example: 5j → { dr: 1, dc: 0, steps: 5 } +``` + +**State Management:** +- `countRef` → Accumulates count digits +- `lastMotionRef` → Stores last motion for repeat +- `pendingGRef` → Tracks first g press for gg + +### Testing Results +✅ All anchor moves working +✅ Count prefixes working (5j, 10l, etc.) +✅ Repeat motion (.) working +✅ 0 works as both anchor and count +✅ gg requires two presses +✅ All moves bounded with red flash feedback + ### Next Steps -- Continue Phase 40: Add vim motions (counts, anchors, repeat) -- Or sidequest before next phase +- Phase 40.3: Implement cell editing (i/r modes) +- Add digit entry (1-9) +- Add erase (x, Backspace) +- Mode indicators --- -## Iteration 7: [Pending] +## Iteration 8: [Pending] *To be filled as implementation progresses...*