From c52656625b9850d0817cf9477e7adb86350e70d9 Mon Sep 17 00:00:00 2001 From: jnjpng Date: Fri, 13 Mar 2026 16:45:59 -0700 Subject: [PATCH] fix: improve bash-mode backspace exit behavior (#1386) Co-authored-by: Letta Code --- src/cli/components/InputRich.tsx | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/cli/components/InputRich.tsx b/src/cli/components/InputRich.tsx index 9495f6f..7fa7074 100644 --- a/src/cli/components/InputRich.tsx +++ b/src/cli/components/InputRich.tsx @@ -803,6 +803,7 @@ export function Input({ // Bash mode state (declared early so prompt width can feed into contentWidth) const [isBashMode, setIsBashMode] = useState(false); + const [bashExitArmed, setBashExitArmed] = useState(false); useEffect(() => { const prev = lastColumnsRef.current; @@ -926,14 +927,21 @@ export function Input({ const handleBangAtEmpty = useCallback(() => { if (isBashMode) return false; setIsBashMode(true); + // Arm immediately so initial empty backspace exits in one press. + setBashExitArmed(true); return true; }, [isBashMode]); const handleBackspaceAtEmpty = useCallback(() => { if (!isBashMode) return false; + if (!bashExitArmed) { + setBashExitArmed(true); + return true; + } setIsBashMode(false); + setBashExitArmed(false); return true; - }, [isBashMode]); + }, [isBashMode, bashExitArmed]); // Reset cursor position after it's been applied useEffect(() => { @@ -943,6 +951,20 @@ export function Input({ } }, [cursorPos]); + // Reset bash exit arming when leaving bash mode + useEffect(() => { + if (!isBashMode && bashExitArmed) { + setBashExitArmed(false); + } + }, [isBashMode, bashExitArmed]); + + // If user types after first backspace-at-empty, disarm exit intent + useEffect(() => { + if (bashExitArmed && value.length > 0) { + setBashExitArmed(false); + } + }, [value, bashExitArmed]); + // Reset boundary flags and preferred column when cursor moves or value changes useEffect(() => { if (currentCursorPosition !== 0) { @@ -1057,6 +1079,7 @@ export function Input({ // First CTRL-C - wipe input and start 1-second timer // Note: In bash mode, this clears input but keeps bash mode active setValue(""); + setBashExitArmed(false); setCtrlCPressed(true); if (ctrlCTimerRef.current) clearTimeout(ctrlCTimerRef.current); ctrlCTimerRef.current = setTimeout(() => {