import { useRef } from 'react'; import type { VimMotionSystem, Motion } from './types'; export function useVimMotions(): VimMotionSystem { const countRef = useRef(''); const lastMotionRef = useRef(null); const processKey = (key: string) => { if (key >= '0' && key <= '9') { if (key === '0' && countRef.current === '') { return { type: 'anchor', data: 'start' }; } countRef.current += key; return { type: 'count', data: key }; } const count = countRef.current ? parseInt(countRef.current, 10) : 1; switch (key) { case 'h': const motionH = { dr: 0, dc: -1, steps: count }; lastMotionRef.current = motionH; countRef.current = ''; return { type: 'move', data: motionH }; case 'j': const motionJ = { dr: 1, dc: 0, steps: count }; lastMotionRef.current = motionJ; countRef.current = ''; return { type: 'move', data: motionJ }; case 'k': const motionK = { dr: -1, dc: 0, steps: count }; lastMotionRef.current = motionK; countRef.current = ''; return { type: 'move', data: motionK }; case 'l': const motionL = { dr: 0, dc: 1, steps: count }; lastMotionRef.current = motionL; countRef.current = ''; return { type: 'move', data: motionL }; case '^': countRef.current = ''; return { type: 'anchor', data: 'start' }; case '$': countRef.current = ''; return { type: 'anchor', data: 'end' }; case 'g': countRef.current = ''; return { type: 'anchor', data: 'top' }; case 'G': countRef.current = ''; return { type: 'anchor', data: 'bottom' }; case '.': const lastMotion = lastMotionRef.current; if (lastMotion) { return { type: 'repeat', data: lastMotion }; } return null; case 'i': countRef.current = ''; return { type: 'mode', data: 'edit' }; case 'Escape': countRef.current = ''; return { type: 'mode', data: 'normal' }; case 'x': case 'Delete': case 'Backspace': countRef.current = ''; return { type: 'erase', data: null }; default: if (key >= '1' && key <= '9') { countRef.current = ''; return { type: 'digit', data: key }; } return null; } }; const resetCount = () => { countRef.current = ''; }; const getCount = () => { return countRef.current ? parseInt(countRef.current, 10) : 1; }; const hasCount = () => { return countRef.current !== ''; }; const setLastMotion = (motion: Motion) => { lastMotionRef.current = motion; }; const repeatLastMotion = () => { return lastMotionRef.current; }; return { processKey, resetCount, getCount, hasCount, setLastMotion, repeatLastMotion }; }