mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-01 15:34:29 -07:00
refactor: migrate to useKeyMatchers hook (#21753)
This commit is contained in:
committed by
GitHub
parent
e406dcc249
commit
ab64b15d51
@@ -11,7 +11,8 @@ import {
|
||||
getAdminErrorMessage,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { useKeypress } from './useKeypress.js';
|
||||
import { keyMatchers, Command } from '../keyMatchers.js';
|
||||
import { Command } from '../keyMatchers.js';
|
||||
import { useKeyMatchers } from './useKeyMatchers.js';
|
||||
import type { HistoryItemWithoutId } from '../types.js';
|
||||
import { MessageType } from '../types.js';
|
||||
|
||||
@@ -30,6 +31,7 @@ export function useApprovalModeIndicator({
|
||||
isActive = true,
|
||||
allowPlanMode = false,
|
||||
}: UseApprovalModeIndicatorArgs): ApprovalMode {
|
||||
const keyMatchers = useKeyMatchers();
|
||||
const currentConfigValue = config.getApprovalMode();
|
||||
const [showApprovalMode, setApprovalMode] = useState(currentConfigValue);
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import type { KeyMatchers } from '../keyMatchers.js';
|
||||
import { defaultKeyMatchers } from '../keyMatchers.js';
|
||||
|
||||
/**
|
||||
* Hook to retrieve the currently active key matchers.
|
||||
* This prepares the codebase for dynamic or custom key bindings in the future.
|
||||
*/
|
||||
export function useKeyMatchers(): KeyMatchers {
|
||||
return useMemo(() => defaultKeyMatchers, []);
|
||||
}
|
||||
@@ -6,8 +6,9 @@
|
||||
|
||||
import { useReducer, useRef, useEffect, useCallback } from 'react';
|
||||
import { useKeypress, type Key } from './useKeypress.js';
|
||||
import { keyMatchers, Command } from '../keyMatchers.js';
|
||||
import { Command } from '../keyMatchers.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import { useKeyMatchers } from './useKeyMatchers.js';
|
||||
|
||||
export interface SelectionListItem<T> {
|
||||
key: string;
|
||||
@@ -290,6 +291,7 @@ export function useSelectionList<T>({
|
||||
focusKey,
|
||||
priority,
|
||||
}: UseSelectionListOptions<T>): UseSelectionListResult {
|
||||
const keyMatchers = useKeyMatchers();
|
||||
const baseItems = toBaseItems(items);
|
||||
|
||||
const [state, dispatch] = useReducer(selectionListReducer, {
|
||||
@@ -460,7 +462,7 @@ export function useSelectionList<T>({
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[dispatch, itemsLength, showNumbers],
|
||||
[dispatch, itemsLength, showNumbers, keyMatchers],
|
||||
);
|
||||
|
||||
useKeypress(handleKeypress, {
|
||||
|
||||
@@ -9,12 +9,18 @@ import { act } from 'react';
|
||||
import { renderHook } from '../../test-utils/render.js';
|
||||
import { useTabbedNavigation } from './useTabbedNavigation.js';
|
||||
import { useKeypress } from './useKeypress.js';
|
||||
import { useKeyMatchers } from './useKeyMatchers.js';
|
||||
import type { KeyMatchers } from '../keyMatchers.js';
|
||||
import type { Key, KeypressHandler } from '../contexts/KeypressContext.js';
|
||||
|
||||
vi.mock('./useKeypress.js', () => ({
|
||||
useKeypress: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('./useKeyMatchers.js', () => ({
|
||||
useKeyMatchers: vi.fn(),
|
||||
}));
|
||||
|
||||
const createKey = (partial: Partial<Key>): Key => ({
|
||||
name: partial.name || '',
|
||||
sequence: partial.sequence || '',
|
||||
@@ -26,13 +32,14 @@ const createKey = (partial: Partial<Key>): Key => ({
|
||||
...partial,
|
||||
});
|
||||
|
||||
const mockKeyMatchers = {
|
||||
'cursor.left': vi.fn((key) => key.name === 'left'),
|
||||
'cursor.right': vi.fn((key) => key.name === 'right'),
|
||||
'dialog.next': vi.fn((key) => key.name === 'tab' && !key.shift),
|
||||
'dialog.previous': vi.fn((key) => key.name === 'tab' && key.shift),
|
||||
} as unknown as KeyMatchers;
|
||||
|
||||
vi.mock('../keyMatchers.js', () => ({
|
||||
keyMatchers: {
|
||||
'cursor.left': vi.fn((key) => key.name === 'left'),
|
||||
'cursor.right': vi.fn((key) => key.name === 'right'),
|
||||
'dialog.next': vi.fn((key) => key.name === 'tab' && !key.shift),
|
||||
'dialog.previous': vi.fn((key) => key.name === 'tab' && key.shift),
|
||||
},
|
||||
Command: {
|
||||
MOVE_LEFT: 'cursor.left',
|
||||
MOVE_RIGHT: 'cursor.right',
|
||||
@@ -45,6 +52,7 @@ describe('useTabbedNavigation', () => {
|
||||
let capturedHandler: KeypressHandler;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(useKeyMatchers).mockReturnValue(mockKeyMatchers);
|
||||
vi.mocked(useKeypress).mockImplementation((handler) => {
|
||||
capturedHandler = handler;
|
||||
});
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
import { useReducer, useCallback, useEffect, useRef } from 'react';
|
||||
import { useKeypress, type Key } from './useKeypress.js';
|
||||
import { keyMatchers, Command } from '../keyMatchers.js';
|
||||
import { Command } from '../keyMatchers.js';
|
||||
import { useKeyMatchers } from './useKeyMatchers.js';
|
||||
|
||||
/**
|
||||
* Options for the useTabbedNavigation hook.
|
||||
@@ -147,6 +148,7 @@ export function useTabbedNavigation({
|
||||
isActive = true,
|
||||
onTabChange,
|
||||
}: UseTabbedNavigationOptions): UseTabbedNavigationResult {
|
||||
const keyMatchers = useKeyMatchers();
|
||||
const [state, dispatch] = useReducer(tabbedNavigationReducer, {
|
||||
currentIndex: Math.max(0, Math.min(initialIndex, tabCount - 1)),
|
||||
tabCount,
|
||||
@@ -231,6 +233,7 @@ export function useTabbedNavigation({
|
||||
goToNextTab,
|
||||
goToPrevTab,
|
||||
isNavigationBlocked,
|
||||
keyMatchers,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ import type { Key } from './useKeypress.js';
|
||||
import type { TextBuffer } from '../components/shared/text-buffer.js';
|
||||
import { useVimMode } from '../contexts/VimModeContext.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import { keyMatchers, Command } from '../keyMatchers.js';
|
||||
import { Command } from '../keyMatchers.js';
|
||||
import { useKeyMatchers } from './useKeyMatchers.js';
|
||||
|
||||
export type VimMode = 'NORMAL' | 'INSERT';
|
||||
|
||||
@@ -152,6 +153,7 @@ const vimReducer = (state: VimState, action: VimAction): VimState => {
|
||||
* @returns Object with vim state and input handler
|
||||
*/
|
||||
export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
|
||||
const keyMatchers = useKeyMatchers();
|
||||
const { vimEnabled, vimMode, setVimMode } = useVimMode();
|
||||
const [state, dispatch] = useReducer(vimReducer, initialVimState);
|
||||
|
||||
@@ -439,7 +441,7 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
|
||||
|
||||
return buffer.handleInput(normalizedKey);
|
||||
},
|
||||
[buffer, dispatch, updateMode, onSubmit, checkDoubleEscape],
|
||||
[buffer, dispatch, updateMode, onSubmit, checkDoubleEscape, keyMatchers],
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -1202,6 +1204,7 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
|
||||
executeCommand,
|
||||
updateMode,
|
||||
checkDoubleEscape,
|
||||
keyMatchers,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user