From 83f46557c0bdccce048e4daea6cabfe609d29edc Mon Sep 17 00:00:00 2001 From: cynthialong0-0 Date: Wed, 13 May 2026 16:46:27 +0000 Subject: [PATCH] fix ctrl c conflict behavior --- packages/cli/src/ui/AppContainer.test.tsx | 17 +++++++++++++ packages/cli/src/ui/AppContainer.tsx | 31 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/ui/AppContainer.test.tsx b/packages/cli/src/ui/AppContainer.test.tsx index 6b1fc93d94..ff87c64e39 100644 --- a/packages/cli/src/ui/AppContainer.test.tsx +++ b/packages/cli/src/ui/AppContainer.test.tsx @@ -2127,6 +2127,23 @@ describe('AppContainer State Management', () => { }); describe('CTRL+C', () => { + it('should not trigger quit flow when input buffer has text', async () => { + mockedUseTextBuffer.mockReturnValue({ + text: 'hello world', + setText: vi.fn(), + lines: ['hello world'], + cursor: [0, 11], + handleInput: vi.fn().mockReturnValue(false), + }); + await setupKeypressTest(); + + pressKey('\x03'); // Ctrl+C + + expect(mockCancelOngoingRequest).not.toHaveBeenCalled(); + expect(mockHandleSlashCommand).not.toHaveBeenCalled(); + unmount(); + }); + it('should cancel ongoing request on first press', async () => { mockedUseGeminiStream.mockReturnValue({ ...DEFAULT_GEMINI_STREAM_MOCK, diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx index d77c9adfb6..27597d5963 100644 --- a/packages/cli/src/ui/AppContainer.tsx +++ b/packages/cli/src/ui/AppContainer.tsx @@ -1649,11 +1649,14 @@ Logging in with Google... Restarting Gemini CLI to continue. [config, handleSlashCommand], ); - const { pressCount: ctrlCPressCount, handlePress: handleCtrlCPress } = - useRepeatedKeyPress({ - windowMs: WARNING_PROMPT_DURATION_MS, - onRepeat: handleExitRepeat, - }); + const { + pressCount: ctrlCPressCount, + handlePress: handleCtrlCPress, + resetCount: resetCtrlCPress, + } = useRepeatedKeyPress({ + windowMs: WARNING_PROMPT_DURATION_MS, + onRepeat: handleExitRepeat, + }); const { pressCount: ctrlDPressCount, handlePress: handleCtrlDPress } = useRepeatedKeyPress({ @@ -1830,6 +1833,20 @@ Logging in with Google... Restarting Gemini CLI to continue. return true; } + if ( + keyMatchers[Command.QUIT](key) && + keyMatchers[Command.CLEAR_INPUT](key) && + isInputActive && + streamingState === StreamingState.Idle && + buffer.text.length > 0 + ) { + // Let InputPrompt handle Ctrl+C as edit.clear when there is text. + // This preserves documented behavior and allows prompt-level state + // (completions/history) to reset correctly. + resetCtrlCPress(); + return false; + } + if (keyMatchers[Command.QUIT](key)) { // If the user presses Ctrl+C, we want to cancel any ongoing requests. // This should happen regardless of the count. @@ -2062,6 +2079,10 @@ Logging in with Google... Restarting Gemini CLI to continue. startRecording, stopRecording, mouseMode, + isInputActive, + streamingState, + buffer, + resetCtrlCPress, ], );