refactor(cli): rename 'return' key to 'enter' internally (#21796)

This commit is contained in:
Tommaso Sciortino
2026-03-10 02:32:40 +00:00
committed by GitHub
parent ec7773eb7b
commit 14412c3a72
19 changed files with 67 additions and 72 deletions

View File

@@ -103,7 +103,7 @@ describe('ApiAuthDialog', () => {
it.each([
{
keyName: 'return',
keyName: 'enter',
sequence: '\r',
expectedCall: onSubmit,
args: ['submitted-key'],

View File

@@ -210,7 +210,7 @@ export const ConfigExtensionDialog: React.FC<ConfigExtensionDialogProps> = ({
useKeypress(
(key: Key) => {
if (state.type === 'ASK_CONFIRMATION') {
if (key.name === 'y' || key.name === 'return') {
if (key.name === 'y' || key.name === 'enter') {
state.resolve(true);
return true;
}
@@ -220,7 +220,7 @@ export const ConfigExtensionDialog: React.FC<ConfigExtensionDialogProps> = ({
}
}
if (state.type === 'DONE' || state.type === 'ERROR') {
if (key.name === 'return' || key.name === 'escape') {
if (key.name === 'enter' || key.name === 'escape') {
onClose();
return true;
}

View File

@@ -972,7 +972,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
if (targetIndex < completion.suggestions.length) {
const suggestion = completion.suggestions[targetIndex];
const isEnterKey = key.name === 'return' && !key.ctrl;
const isEnterKey = key.name === 'enter' && !key.ctrl;
if (isEnterKey && shellModeActive) {
if (hasUserNavigatedSuggestions.current) {

View File

@@ -324,7 +324,7 @@ describe('SessionBrowser component', () => {
await waitUntilReady();
// Press Enter.
triggerKey({ name: 'return', sequence: '\r' });
triggerKey({ name: 'enter', sequence: '\r' });
await waitUntilReady();
expect(onResumeSession).toHaveBeenCalledTimes(1);
@@ -367,7 +367,7 @@ describe('SessionBrowser component', () => {
await waitUntilReady();
// Active selection is at 0 (current session).
triggerKey({ name: 'return', sequence: '\r' });
triggerKey({ name: 'enter', sequence: '\r' });
await waitUntilReady();
expect(onResumeSession).not.toHaveBeenCalled();

View File

@@ -873,7 +873,7 @@ export const useSessionBrowserInput = (
// Handling regardless of search mode.
if (
key.name === 'return' &&
key.name === 'enter' &&
state.filteredAndSortedSessions[state.activeIndex]
) {
const selectedSession =

View File

@@ -287,7 +287,7 @@ describe('TextInput', () => {
await act(async () => {
keypressHandler({
name: 'return',
name: 'enter',
shift: false,
alt: false,
ctrl: false,
@@ -314,7 +314,7 @@ describe('TextInput', () => {
await act(async () => {
keypressHandler({
name: 'return',
name: 'enter',
shift: false,
alt: false,
ctrl: false,
@@ -339,7 +339,7 @@ describe('TextInput', () => {
await act(async () => {
keypressHandler({
name: 'return',
name: 'enter',
shift: false,
alt: false,
ctrl: false,

View File

@@ -1533,7 +1533,7 @@ describe('useTextBuffer', () => {
const { result } = renderHook(() => useTextBuffer({ viewport }));
act(() => {
result.current.handleInput({
name: 'return',
name: 'enter',
shift: false,
alt: false,
ctrl: false,
@@ -1789,7 +1789,7 @@ describe('useTextBuffer', () => {
const { result } = renderHook(() => useTextBuffer({ viewport }));
act(() => {
result.current.handleInput({
name: 'return',
name: 'enter',
shift: true,
alt: false,
ctrl: false,
@@ -2290,7 +2290,7 @@ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
);
act(() => {
result.current.handleInput({
name: 'return',
name: 'enter',
shift: false,
alt: false,
ctrl: false,

View File

@@ -100,7 +100,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
name: 'enter',
shift: false,
ctrl: false,
cmd: false,
@@ -115,7 +115,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
name: 'enter',
shift: true,
ctrl: false,
cmd: false,
@@ -148,7 +148,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
name: 'enter',
...expected,
}),
);
@@ -177,7 +177,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
name: 'enter',
shift: false,
alt: true,
ctrl: false,
@@ -216,7 +216,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenLastCalledWith(
expect.objectContaining({
name: 'return',
name: 'enter',
sequence: '\r',
insertable: true,
shift: true,
@@ -238,7 +238,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenLastCalledWith(
expect.objectContaining({
name: 'return',
name: 'enter',
shift: false,
alt: false,
ctrl: false,
@@ -638,8 +638,8 @@ describe('KeypressContext', () => {
describe('Parameterized functional keys', () => {
it.each([
// ModifyOtherKeys
{ sequence: `\x1b[27;2;13~`, expected: { name: 'return', shift: true } },
{ sequence: `\x1b[27;5;13~`, expected: { name: 'return', ctrl: true } },
{ sequence: `\x1b[27;2;13~`, expected: { name: 'enter', shift: true } },
{ sequence: `\x1b[27;5;13~`, expected: { name: 'enter', ctrl: true } },
{ sequence: `\x1b[27;5;9~`, expected: { name: 'tab', ctrl: true } },
{
sequence: `\x1b[27;6;9~`,
@@ -1124,7 +1124,7 @@ describe('KeypressContext', () => {
expect(keyHandler).toHaveBeenNthCalledWith(
1,
expect.objectContaining({
name: 'return',
name: 'enter',
}),
);
expect(keyHandler).toHaveBeenNthCalledWith(

View File

@@ -92,11 +92,11 @@ const KEY_INFO_MAP: Record<
'[[5~': { name: 'pageup' },
'[[6~': { name: 'pagedown' },
'[9u': { name: 'tab' },
'[13u': { name: 'return' },
'[13u': { name: 'enter' },
'[27u': { name: 'escape' },
'[32u': { name: 'space' },
'[127u': { name: 'backspace' },
'[57414u': { name: 'return' }, // Numpad Enter
'[57414u': { name: 'enter' }, // Numpad Enter
'[a': { name: 'up', shift: true },
'[b': { name: 'down', shift: true },
'[c': { name: 'right', shift: true },
@@ -186,10 +186,10 @@ function bufferFastReturn(keypressHandler: KeypressHandler): KeypressHandler {
let lastKeyTime = 0;
return (key: Key) => {
const now = Date.now();
if (key.name === 'return' && now - lastKeyTime <= FAST_RETURN_TIMEOUT) {
if (key.name === 'enter' && now - lastKeyTime <= FAST_RETURN_TIMEOUT) {
keypressHandler({
...key,
name: 'return',
name: 'enter',
shift: true, // to make it a newline, not a submission
alt: false,
ctrl: false,
@@ -232,7 +232,7 @@ function bufferBackslashEnter(
if (nextKey === null) {
keypressHandler(key);
} else if (nextKey.name === 'return') {
} else if (nextKey.name === 'enter') {
keypressHandler({
...nextKey,
shift: true,
@@ -582,11 +582,11 @@ function* emitKeys(
}
} else if (ch === '\r') {
// carriage return
name = 'return';
name = 'enter';
alt = escaped;
} else if (escaped && ch === '\n') {
// Alt+Enter (linefeed), should be consistent with carriage return
name = 'return';
name = 'enter';
alt = escaped;
} else if (ch === '\t') {
// tab

View File

@@ -111,7 +111,7 @@ describe(`useKeypress`, () => {
it('should correctly identify alt+enter (meta key)', () => {
renderKeypressHook(true);
const key = { name: 'return', sequence: '\x1B\r' };
const key = { name: 'enter', sequence: '\x1B\r' };
act(() => stdin.write(key.sequence));
expect(onKeypress).toHaveBeenCalledWith(
expect.objectContaining({

View File

@@ -356,7 +356,7 @@ describe('useSelectionList', () => {
initialIndex: 2,
onSelect: mockOnSelect,
});
pressKey('return');
pressKey('enter');
await waitUntilReady();
expect(mockOnSelect).toHaveBeenCalledTimes(1);
expect(mockOnSelect).toHaveBeenCalledWith('C');
@@ -371,7 +371,7 @@ describe('useSelectionList', () => {
act(() => result.current.setActiveIndex(1));
await waitUntilReady();
pressKey('return');
pressKey('enter');
await waitUntilReady();
expect(mockOnSelect).not.toHaveBeenCalled();
});
@@ -415,7 +415,7 @@ describe('useSelectionList', () => {
await waitUntilReady();
// 3. Press Enter. Should select D.
act(() => {
press('return');
press('enter');
});
await waitUntilReady();
@@ -459,7 +459,7 @@ describe('useSelectionList', () => {
// All presses happen in same render cycle - React batches the state updates
press('down'); // Should move 0 (A) -> 2 (C)
press('down'); // Should move 2 (C) -> 3 (D)
press('return'); // Should select D
press('enter'); // Should select D
});
await waitUntilReady();
@@ -759,7 +759,7 @@ describe('useSelectionList', () => {
pressNumber('1');
await waitUntilReady();
pressKey('return');
pressKey('enter');
await waitUntilReady();
expect(mockOnSelect).toHaveBeenCalledTimes(1);

View File

@@ -396,7 +396,7 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
// In INSERT mode, let InputPrompt handle completion keys and special commands
if (
normalizedKey.name === 'tab' ||
(normalizedKey.name === 'return' && !normalizedKey.ctrl) ||
(normalizedKey.name === 'enter' && !normalizedKey.ctrl) ||
normalizedKey.name === 'up' ||
normalizedKey.name === 'down' ||
(normalizedKey.ctrl && normalizedKey.name === 'r')
@@ -424,7 +424,7 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
// Special handling for Enter key to allow command submission (lower priority than completion)
if (
normalizedKey.name === 'return' &&
normalizedKey.name === 'enter' &&
!normalizedKey.alt &&
!normalizedKey.ctrl &&
!normalizedKey.cmd

View File

@@ -80,8 +80,8 @@ describe('KeyBinding', () => {
});
it('should handle named keys with modifiers', () => {
const binding = new KeyBinding('ctrl+return');
expect(binding.key).toBe('return');
const binding = new KeyBinding('ctrl+enter');
expect(binding.key).toBe('enter');
expect(binding.ctrl).toBe(true);
});

View File

@@ -149,11 +149,9 @@ export class KeyBinding {
'numpad_subtract',
'numpad_decimal',
'numpad_divide',
// Gemini CLI legacy/internal support
'return',
]);
/** The key name (e.g., 'a', 'return', 'tab', 'escape') */
/** The key name (e.g., 'a', 'enter', 'tab', 'escape') */
readonly key: string;
readonly shift: boolean;
readonly alt: boolean;
@@ -238,7 +236,7 @@ export type KeyBindingConfig = {
*/
export const defaultKeyBindings: KeyBindingConfig = {
// Basic Controls
[Command.RETURN]: [new KeyBinding('return')],
[Command.RETURN]: [new KeyBinding('enter')],
[Command.ESCAPE]: [new KeyBinding('escape'), new KeyBinding('ctrl+[')],
[Command.QUIT]: [new KeyBinding('ctrl+c')],
[Command.EXIT]: [new KeyBinding('ctrl+d')],
@@ -308,7 +306,7 @@ export const defaultKeyBindings: KeyBindingConfig = {
[Command.HISTORY_UP]: [new KeyBinding('ctrl+p')],
[Command.HISTORY_DOWN]: [new KeyBinding('ctrl+n')],
[Command.REVERSE_SEARCH]: [new KeyBinding('ctrl+r')],
[Command.SUBMIT_REVERSE_SEARCH]: [new KeyBinding('return')],
[Command.SUBMIT_REVERSE_SEARCH]: [new KeyBinding('enter')],
[Command.ACCEPT_SUGGESTION_REVERSE_SEARCH]: [new KeyBinding('tab')],
// Navigation
@@ -325,10 +323,7 @@ export const defaultKeyBindings: KeyBindingConfig = {
[Command.DIALOG_PREV]: [new KeyBinding('shift+tab')],
// Suggestions & Completions
[Command.ACCEPT_SUGGESTION]: [
new KeyBinding('tab'),
new KeyBinding('return'),
],
[Command.ACCEPT_SUGGESTION]: [new KeyBinding('tab'), new KeyBinding('enter')],
[Command.COMPLETION_UP]: [new KeyBinding('up'), new KeyBinding('ctrl+p')],
[Command.COMPLETION_DOWN]: [new KeyBinding('down'), new KeyBinding('ctrl+n')],
[Command.EXPAND_SUGGESTION]: [new KeyBinding('right')],
@@ -336,12 +331,12 @@ export const defaultKeyBindings: KeyBindingConfig = {
// Text Input
// Must also exclude shift to allow shift+enter for newline
[Command.SUBMIT]: [new KeyBinding('return')],
[Command.SUBMIT]: [new KeyBinding('enter')],
[Command.NEWLINE]: [
new KeyBinding('ctrl+return'),
new KeyBinding('cmd+return'),
new KeyBinding('alt+return'),
new KeyBinding('shift+return'),
new KeyBinding('ctrl+enter'),
new KeyBinding('cmd+enter'),
new KeyBinding('alt+enter'),
new KeyBinding('shift+enter'),
new KeyBinding('ctrl+j'),
],
[Command.OPEN_EXTERNAL_EDITOR]: [new KeyBinding('ctrl+x')],
@@ -366,7 +361,7 @@ export const defaultKeyBindings: KeyBindingConfig = {
[Command.UNFOCUS_BACKGROUND_SHELL_LIST]: [new KeyBinding('tab')],
[Command.SHOW_BACKGROUND_SHELL_UNFOCUS_WARNING]: [new KeyBinding('tab')],
[Command.SHOW_SHELL_INPUT_UNFOCUS_WARNING]: [new KeyBinding('tab')],
[Command.BACKGROUND_SHELL_SELECT]: [new KeyBinding('return')],
[Command.BACKGROUND_SHELL_SELECT]: [new KeyBinding('enter')],
[Command.BACKGROUND_SHELL_ESCAPE]: [new KeyBinding('escape')],
[Command.SHOW_MORE_LINES]: [new KeyBinding('ctrl+o')],
[Command.EXPAND_PASTE]: [new KeyBinding('ctrl+o')],

View File

@@ -31,7 +31,7 @@ describe('keyMatchers', () => {
// Basic bindings
{
command: Command.RETURN,
positive: [createKey('return')],
positive: [createKey('enter')],
negative: [createKey('r')],
},
{
@@ -270,8 +270,8 @@ describe('keyMatchers', () => {
// Auto-completion
{
command: Command.ACCEPT_SUGGESTION,
positive: [createKey('tab'), createKey('return')],
negative: [createKey('return', { ctrl: true }), createKey('space')],
positive: [createKey('tab'), createKey('enter')],
negative: [createKey('enter', { ctrl: true }), createKey('space')],
},
{
command: Command.COMPLETION_UP,
@@ -287,21 +287,21 @@ describe('keyMatchers', () => {
// Text input
{
command: Command.SUBMIT,
positive: [createKey('return')],
positive: [createKey('enter')],
negative: [
createKey('return', { ctrl: true }),
createKey('return', { cmd: true }),
createKey('return', { alt: true }),
createKey('enter', { ctrl: true }),
createKey('enter', { cmd: true }),
createKey('enter', { alt: true }),
],
},
{
command: Command.NEWLINE,
positive: [
createKey('return', { ctrl: true }),
createKey('return', { cmd: true }),
createKey('return', { alt: true }),
createKey('enter', { ctrl: true }),
createKey('enter', { cmd: true }),
createKey('enter', { alt: true }),
],
negative: [createKey('return'), createKey('n')],
negative: [createKey('enter'), createKey('n')],
},
// External tools
@@ -382,14 +382,14 @@ describe('keyMatchers', () => {
},
{
command: Command.SUBMIT_REVERSE_SEARCH,
positive: [createKey('return')],
negative: [createKey('return', { ctrl: true }), createKey('tab')],
positive: [createKey('enter')],
negative: [createKey('enter', { ctrl: true }), createKey('tab')],
},
{
command: Command.ACCEPT_SUGGESTION_REVERSE_SEARCH,
positive: [createKey('tab')],
negative: [
createKey('return'),
createKey('enter'),
createKey('space'),
createKey('tab', { ctrl: true }),
],

View File

@@ -21,7 +21,7 @@ const SPECIAL_KEYS: Record<string, string> = {
end: '\x1b[F',
pageup: '\x1b[5~',
pagedown: '\x1b[6~',
return: '\r',
enter: '\r',
};
/**

View File

@@ -27,7 +27,7 @@ describe('keybindingUtils', () => {
},
{
name: 'named key (return)',
binding: new KeyBinding('return'),
binding: new KeyBinding('enter'),
expected: {
darwin: 'Enter',
win32: 'Enter',

View File

@@ -16,7 +16,7 @@ import {
* Maps internal key names to user-friendly display names.
*/
const KEY_NAME_MAP: Record<string, string> = {
return: 'Enter',
enter: 'Enter',
escape: 'Esc',
backspace: 'Backspace',
delete: 'Delete',