0 works both ways now
This commit is contained in:
+7
-6
@@ -90,12 +90,13 @@ export type CursorManager = {
|
||||
moveToTop: () => void;
|
||||
moveToBottom: () => void;
|
||||
repeatLastMotion: () => void;
|
||||
resetCount: () => void;
|
||||
getCount: () => string;
|
||||
setCount: (digit: string) => void;
|
||||
setLastKey: (key: string) => void;
|
||||
getLastKey: () => string;
|
||||
hero?: UseHeroType;
|
||||
resetCount: () => void;
|
||||
getCount: () => string;
|
||||
hasCount: () => boolean;
|
||||
setCount: (digit: string) => void;
|
||||
setLastKey: (key: string) => void;
|
||||
getLastKey: () => string;
|
||||
hero?: UseHeroType;
|
||||
}
|
||||
|
||||
export type HeroManager = {
|
||||
|
||||
+80
-75
@@ -12,7 +12,7 @@ function validateAnchorMove(direction: 'start' | 'end' | 'top' | 'bottom', curre
|
||||
|
||||
const navigator = useMazeNavigation(board.mazeRef.current);
|
||||
const target = navigator.findAnchorTarget(currentPos, navDirection);
|
||||
|
||||
|
||||
if (!target) return false;
|
||||
|
||||
const dr = target.row > currentPos.row ? 1 :
|
||||
@@ -78,61 +78,61 @@ export function useCursor(board: BoardManager, gameStatusManager: GameStatusMana
|
||||
move(0, 1, count);
|
||||
}
|
||||
|
||||
function moveToAnchor(target: 'start' | 'end' | 'top' | 'bottom'): void {
|
||||
const currentPos = position.current;
|
||||
const direction = target === 'start' ? 'left' :
|
||||
target === 'end' ? 'right' :
|
||||
target === 'top' ? 'top' : 'bottom';
|
||||
function moveToAnchor(target: 'start' | 'end' | 'top' | 'bottom'): void {
|
||||
const currentPos = position.current;
|
||||
const direction = target === 'start' ? 'left' :
|
||||
target === 'end' ? 'right' :
|
||||
target === 'top' ? 'top' : 'bottom';
|
||||
|
||||
const anchorTarget = navigator.findAnchorTarget(currentPos, direction);
|
||||
if (!anchorTarget) return;
|
||||
const anchorTarget = navigator.findAnchorTarget(currentPos, direction);
|
||||
if (!anchorTarget) return;
|
||||
|
||||
const dr = anchorTarget.row > currentPos.row ? 1 :
|
||||
anchorTarget.row < currentPos.row ? -1 : 0;
|
||||
const dc = anchorTarget.col > currentPos.col ? 1 :
|
||||
anchorTarget.col < currentPos.col ? -1 : 0;
|
||||
const steps = Math.abs(anchorTarget.row - currentPos.row) + Math.abs(anchorTarget.col - currentPos.col);
|
||||
const dr = anchorTarget.row > currentPos.row ? 1 :
|
||||
anchorTarget.row < currentPos.row ? -1 : 0;
|
||||
const dc = anchorTarget.col > currentPos.col ? 1 :
|
||||
anchorTarget.col < currentPos.col ? -1 : 0;
|
||||
const steps = Math.abs(anchorTarget.row - currentPos.row) + Math.abs(anchorTarget.col - currentPos.col);
|
||||
|
||||
position.current = anchorTarget;
|
||||
if (hero && hero.heroPos) {
|
||||
hero.moveTo(anchorTarget);
|
||||
if (steps > 0) {
|
||||
vimMotions.setLastMotion({ dr, dc, steps });
|
||||
}
|
||||
}
|
||||
}
|
||||
position.current = anchorTarget;
|
||||
if (hero && hero.heroPos) {
|
||||
hero.moveTo(anchorTarget);
|
||||
if (steps > 0) {
|
||||
vimMotions.setLastMotion({ dr, dc, steps });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function moveToStart(): void {
|
||||
if (!validateAnchorMove('start', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('start');
|
||||
}
|
||||
function moveToStart(): void {
|
||||
if (!validateAnchorMove('start', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('start');
|
||||
}
|
||||
|
||||
function moveToEnd(): void {
|
||||
if (!validateAnchorMove('end', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('end');
|
||||
}
|
||||
function moveToEnd(): void {
|
||||
if (!validateAnchorMove('end', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('end');
|
||||
}
|
||||
|
||||
function moveToTop(): void {
|
||||
if (!validateAnchorMove('top', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('top');
|
||||
}
|
||||
function moveToTop(): void {
|
||||
if (!validateAnchorMove('top', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('top');
|
||||
}
|
||||
|
||||
function moveToBottom(): void {
|
||||
if (!validateAnchorMove('bottom', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('bottom');
|
||||
}
|
||||
function moveToBottom(): void {
|
||||
if (!validateAnchorMove('bottom', position.current, board)) {
|
||||
window.dispatchEvent(new Event("maze-invalid"));
|
||||
return;
|
||||
}
|
||||
moveToAnchor('bottom');
|
||||
}
|
||||
|
||||
function repeatLastMotion(): void {
|
||||
const motion = vimMotions.repeatLastMotion();
|
||||
@@ -156,13 +156,17 @@ export function useCursor(board: BoardManager, gameStatusManager: GameStatusMana
|
||||
vimMotions.resetCount();
|
||||
}
|
||||
|
||||
function getCount(): string {
|
||||
return String(vimMotions.getCount());
|
||||
}
|
||||
function getCount(): string {
|
||||
return String(vimMotions.getCount());
|
||||
}
|
||||
|
||||
function setCount(digit: string): void {
|
||||
vimMotions.processKey(digit);
|
||||
}
|
||||
function hasCount(): boolean {
|
||||
return vimMotions.hasCount();
|
||||
}
|
||||
|
||||
function setCount(digit: string): void {
|
||||
vimMotions.processKey(digit);
|
||||
}
|
||||
|
||||
function setLastKey(key: string): void {
|
||||
lastKeyRef.current = key;
|
||||
@@ -172,26 +176,27 @@ export function useCursor(board: BoardManager, gameStatusManager: GameStatusMana
|
||||
return lastKeyRef.current;
|
||||
}
|
||||
|
||||
const cursor = {
|
||||
position: () => position.current,
|
||||
mode: () => mode.current,
|
||||
move,
|
||||
moveLeft,
|
||||
moveRight,
|
||||
moveUp,
|
||||
moveDown,
|
||||
moveToStart,
|
||||
moveToEnd,
|
||||
moveToTop,
|
||||
moveToBottom,
|
||||
repeatLastMotion,
|
||||
resetCount,
|
||||
getCount,
|
||||
setCount,
|
||||
setLastKey,
|
||||
getLastKey,
|
||||
hero,
|
||||
}
|
||||
const cursor = {
|
||||
position: () => position.current,
|
||||
mode: () => mode.current,
|
||||
move,
|
||||
moveLeft,
|
||||
moveRight,
|
||||
moveUp,
|
||||
moveDown,
|
||||
moveToStart,
|
||||
moveToEnd,
|
||||
moveToTop,
|
||||
moveToBottom,
|
||||
repeatLastMotion,
|
||||
resetCount,
|
||||
getCount,
|
||||
hasCount,
|
||||
setCount,
|
||||
setLastKey,
|
||||
getLastKey,
|
||||
hero,
|
||||
}
|
||||
|
||||
const keyManager = useGameKeys({ cursor, gameStatusManager });
|
||||
|
||||
|
||||
@@ -34,17 +34,15 @@ export const useGameKeys = (props: UseGameKeysParams) => {
|
||||
const handler = (ev: KeyboardEvent) => {
|
||||
if (["waiting", "game-over", "game-won"].includes(gameStatus)) return;
|
||||
|
||||
// "0" behaves like Vim: beginning of line
|
||||
if (ev.key === "0" && cursor.getCount() === "") {
|
||||
recordKey("0");
|
||||
cursor.resetCount();
|
||||
cursor.moveToStart();
|
||||
return;
|
||||
}
|
||||
if (ev.key === "0" && !cursor.hasCount()) {
|
||||
recordKey("0");
|
||||
cursor.resetCount();
|
||||
cursor.moveToStart();
|
||||
return;
|
||||
}
|
||||
|
||||
const isDigit = ev.key >= "0" && ev.key <= "9";
|
||||
if (isDigit) {
|
||||
if (ev.key === "0" && cursor.getCount() === "") return;
|
||||
recordKey(ev.key);
|
||||
cursor.setCount(ev.key);
|
||||
return;
|
||||
|
||||
@@ -6,6 +6,7 @@ export type VimMotionSystem = {
|
||||
processKey: (key: string) => { type: 'move'|'anchor'|'repeat'|'count', data: any } | null;
|
||||
resetCount: () => void;
|
||||
getCount: () => number;
|
||||
hasCount: () => boolean;
|
||||
setLastMotion: (motion: Motion) => void;
|
||||
repeatLastMotion: () => Motion | null;
|
||||
};
|
||||
@@ -98,10 +99,15 @@ export function useVimMotions(): VimMotionSystem {
|
||||
return lastMotionRef.current;
|
||||
}
|
||||
|
||||
function hasCount(): boolean {
|
||||
return countRef.current !== '';
|
||||
}
|
||||
|
||||
return {
|
||||
processKey,
|
||||
resetCount,
|
||||
getCount,
|
||||
hasCount,
|
||||
setLastMotion,
|
||||
repeatLastMotion
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user