summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/cli/src/gemini.tsx1
-rw-r--r--packages/cli/src/ui/App.tsx35
2 files changed, 35 insertions, 1 deletions
diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx
index e7ab6baa..0ed27a99 100644
--- a/packages/cli/src/gemini.tsx
+++ b/packages/cli/src/gemini.tsx
@@ -78,6 +78,7 @@ async function main() {
startupWarnings={startupWarnings}
/>
</React.StrictMode>,
+ { exitOnCtrlC: false },
);
return;
}
diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx
index 90426ccc..e1657984 100644
--- a/packages/cli/src/ui/App.tsx
+++ b/packages/cli/src/ui/App.tsx
@@ -44,6 +44,8 @@ import { useLogger } from './hooks/useLogger.js';
import { StreamingContext } from './contexts/StreamingContext.js';
import { useGitBranchName } from './hooks/useGitBranchName.js';
+const CTRL_C_PROMPT_DURATION_MS = 1000;
+
interface AppProps {
config: Config;
settings: LoadedSettings;
@@ -77,18 +79,43 @@ export const App = ({
const [corgiMode, setCorgiMode] = useState(false);
const [shellModeActive, setShellModeActive] = useState(false);
const [showErrorDetails, setShowErrorDetails] = useState<boolean>(false);
+ const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
+ const ctrlCTimerRef = useRef<NodeJS.Timeout | null>(null);
const errorCount = useMemo(
() => consoleMessages.filter((msg) => msg.type === 'error').length,
[consoleMessages],
);
+
useInput((input: string, key: InkKeyType) => {
if (key.ctrl && input === 'o') {
setShowErrorDetails((prev) => !prev);
refreshStatic();
+ } else if (key.ctrl && (input === 'c' || input === 'C')) {
+ if (ctrlCPressedOnce) {
+ if (ctrlCTimerRef.current) {
+ clearTimeout(ctrlCTimerRef.current);
+ }
+ process.exit(0);
+ } else {
+ setCtrlCPressedOnce(true);
+ ctrlCTimerRef.current = setTimeout(() => {
+ setCtrlCPressedOnce(false);
+ ctrlCTimerRef.current = null;
+ }, CTRL_C_PROMPT_DURATION_MS);
+ }
}
});
+ useEffect(
+ () => () => {
+ if (ctrlCTimerRef.current) {
+ clearTimeout(ctrlCTimerRef.current);
+ }
+ },
+ [],
+ );
+
useConsolePatcher({
onNewMessage: handleNewMessage,
debugMode: config.getDebugMode(),
@@ -365,11 +392,17 @@ export const App = ({
{process.env.GEMINI_SYSTEM_MD && (
<Text color={Colors.AccentRed}>|⌐■_■| </Text>
)}
- {geminiMdFileCount > 0 && (
+ {ctrlCPressedOnce ? (
+ <Text color={Colors.AccentYellow}>
+ Press Ctrl+C again to exit.
+ </Text>
+ ) : geminiMdFileCount > 0 ? (
<Text color={Colors.SubtleComment}>
Using {geminiMdFileCount} GEMINI.md file
{geminiMdFileCount > 1 ? 's' : ''}
</Text>
+ ) : (
+ <Text> </Text> // Render an empty space to reserve height
)}
</Box>
<Box>