Files
gemini-cli/packages/cli/src/ui/key/keyMatchers.ts
2026-03-11 01:05:50 +00:00

79 lines
1.8 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type { Key } from '../hooks/useKeypress.js';
import type { KeyBindingConfig } from './keyBindings.js';
import {
Command,
defaultKeyBindingConfig,
loadCustomKeybindings,
} from './keyBindings.js';
/**
* Checks if a key matches any of the bindings for a command
*/
function matchCommand(
command: Command,
key: Key,
config: KeyBindingConfig = defaultKeyBindingConfig,
): boolean {
const bindings = config.get(command);
if (!bindings) return false;
return bindings.some((binding) => binding.matches(key));
}
/**
* Key matcher function type
*/
type KeyMatcher = (key: Key) => boolean;
/**
* Type for key matchers mapped to Command enum
*/
export type KeyMatchers = {
readonly [C in Command]: KeyMatcher;
};
/**
* Creates key matchers from a key binding configuration
*/
export function createKeyMatchers(
config: KeyBindingConfig = defaultKeyBindingConfig,
): KeyMatchers {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const matchers = {} as { [C in Command]: KeyMatcher };
for (const command of Object.values(Command)) {
matchers[command] = (key: Key) => matchCommand(command, key, config);
}
return matchers as KeyMatchers;
}
/**
* Default key binding matchers using the default configuration
*/
export const defaultKeyMatchers: KeyMatchers = createKeyMatchers(
defaultKeyBindingConfig,
);
// Re-export Command for convenience
export { Command };
/**
* Loads and creates key matchers including user customizations.
*/
export async function loadKeyMatchers(): Promise<{
matchers: KeyMatchers;
errors: string[];
}> {
const { config, errors } = await loadCustomKeybindings();
return {
matchers: createKeyMatchers(config),
errors,
};
}