mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 18:44:30 -07:00
complete
This commit is contained in:
@@ -143,7 +143,7 @@ export const defaultKeyBindings: KeyBindingConfig = {
|
||||
// Editing
|
||||
[Command.KILL_LINE_RIGHT]: [{ key: 'k', ctrl: true }],
|
||||
[Command.KILL_LINE_LEFT]: [{ key: 'u', ctrl: true }],
|
||||
[Command.CLEAR_INPUT]: [{ key: 'c', ctrl: true }],
|
||||
[Command.CLEAR_INPUT]: [{ key: 'escape' }],
|
||||
// Added command (meta/alt/option) for mac compatibility
|
||||
[Command.DELETE_WORD_BACKWARD]: [
|
||||
{ key: 'backspace', ctrl: true },
|
||||
|
||||
@@ -1253,25 +1253,6 @@ describe('InputPrompt', () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should clear the buffer on Ctrl+C if it has text', async () => {
|
||||
await act(async () => {
|
||||
props.buffer.setText('some text to clear');
|
||||
});
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />, {
|
||||
uiActions,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\x03'); // Ctrl+C character
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(props.buffer.setText).toHaveBeenCalledWith('');
|
||||
expect(mockCommandCompletion.resetCompletionState).toHaveBeenCalled();
|
||||
});
|
||||
expect(props.onSubmit).not.toHaveBeenCalled();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should NOT clear the buffer on Ctrl+C if it is empty', async () => {
|
||||
props.buffer.text = '';
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />, {
|
||||
@@ -1874,7 +1855,7 @@ describe('InputPrompt', () => {
|
||||
beforeEach(() => vi.useFakeTimers());
|
||||
afterEach(() => vi.useRealTimers());
|
||||
|
||||
it('should clear buffer on Ctrl-C', async () => {
|
||||
it('should NOT clear buffer on Ctrl-C', async () => {
|
||||
const onEscapePromptChange = vi.fn();
|
||||
props.onEscapePromptChange = onEscapePromptChange;
|
||||
props.buffer.setText('text to clear');
|
||||
@@ -1887,16 +1868,16 @@ describe('InputPrompt', () => {
|
||||
stdin.write('\x03');
|
||||
vi.advanceTimersByTime(100);
|
||||
|
||||
expect(props.buffer.setText).toHaveBeenCalledWith('');
|
||||
expect(mockCommandCompletion.resetCompletionState).toHaveBeenCalled();
|
||||
expect(props.buffer.setText).not.toHaveBeenCalledWith('');
|
||||
});
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should submit /rewind on double ESC', async () => {
|
||||
it('should submit /rewind on double ESC when buffer is empty', async () => {
|
||||
const onEscapePromptChange = vi.fn();
|
||||
props.onEscapePromptChange = onEscapePromptChange;
|
||||
props.buffer.setText('some text');
|
||||
props.buffer.setText('');
|
||||
vi.mocked(props.buffer.setText).mockClear();
|
||||
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
@@ -1911,6 +1892,26 @@ describe('InputPrompt', () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should clear the buffer on esc esc if it has text', async () => {
|
||||
const onEscapePromptChange = vi.fn();
|
||||
props.onEscapePromptChange = onEscapePromptChange;
|
||||
props.buffer.setText('some text');
|
||||
vi.mocked(props.buffer.setText).mockClear();
|
||||
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\x1B\x1B');
|
||||
vi.advanceTimersByTime(100);
|
||||
|
||||
expect(props.buffer.setText).toHaveBeenCalledWith('');
|
||||
expect(props.onSubmit).not.toHaveBeenCalledWith('/rewind');
|
||||
});
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should reset escape state on any non-ESC key', async () => {
|
||||
const onEscapePromptChange = vi.fn();
|
||||
props.onEscapePromptChange = onEscapePromptChange;
|
||||
|
||||
@@ -495,7 +495,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle double ESC for rewind
|
||||
// Handle double ESC
|
||||
if (escPressCount.current === 0) {
|
||||
escPressCount.current = 1;
|
||||
setShowEscapePrompt(true);
|
||||
@@ -506,9 +506,14 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
resetEscapeState();
|
||||
}, 500);
|
||||
} else {
|
||||
// Second ESC triggers rewind
|
||||
// Second ESC
|
||||
resetEscapeState();
|
||||
onSubmit('/rewind');
|
||||
if (keyMatchers[Command.CLEAR_INPUT](key) && buffer.text.length > 0) {
|
||||
buffer.setText('');
|
||||
resetCompletionState();
|
||||
} else {
|
||||
onSubmit('/rewind');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -790,15 +795,6 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
buffer.move('end');
|
||||
return;
|
||||
}
|
||||
// Ctrl+C (Clear input)
|
||||
if (keyMatchers[Command.CLEAR_INPUT](key)) {
|
||||
if (buffer.text.length > 0) {
|
||||
buffer.setText('');
|
||||
resetCompletionState();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Kill line commands
|
||||
if (keyMatchers[Command.KILL_LINE_RIGHT](key)) {
|
||||
buffer.killLineRight();
|
||||
|
||||
@@ -45,7 +45,12 @@ export const StatusDisplay: React.FC<StatusDisplayProps> = ({
|
||||
}
|
||||
|
||||
if (uiState.showEscapePrompt) {
|
||||
return <Text color={theme.text.secondary}>Press Esc again to rewind.</Text>;
|
||||
const isPromptEmpty = uiState.buffer.text.trim().length === 0;
|
||||
return (
|
||||
<Text color={theme.text.secondary}>
|
||||
Press Esc again to {isPromptEmpty ? 'rewind' : 'clear prompt'}.
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
if (uiState.queueErrorMessage) {
|
||||
|
||||
@@ -96,8 +96,12 @@ describe('keyMatchers', () => {
|
||||
},
|
||||
{
|
||||
command: Command.CLEAR_INPUT,
|
||||
positive: [createKey('c', { ctrl: true })],
|
||||
negative: [createKey('c'), createKey('k', { ctrl: true })],
|
||||
positive: [createKey('escape')],
|
||||
negative: [
|
||||
createKey('c', { ctrl: true }),
|
||||
createKey('c'),
|
||||
createKey('k', { ctrl: true }),
|
||||
],
|
||||
},
|
||||
{
|
||||
command: Command.DELETE_CHAR_LEFT,
|
||||
|
||||
Reference in New Issue
Block a user