starting new structure
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { useRef } from 'react';
|
||||
import type { VimMotionSystem, Motion } from './types';
|
||||
|
||||
export function useVimMotions(): VimMotionSystem {
|
||||
const countRef = useRef<string>('');
|
||||
const lastMotionRef = useRef<Motion | null>(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
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user