Skip to content

Commit 4ad692d

Browse files
committed
fix(cli): fix input history navigation after mode changes (e.g., feedback mode)
- Add isNavigatingRef flag to prevent useEffect reset during cross-mode navigation - Allow Ctrl+V paste in feedback mode by whitelisting it in keyboard-actions.ts - Fix logic order in chat-input-bar.tsx to check suggestion menus before history - Eliminate code duplication by having useEffect call resetHistoryNavigation() - Add comprehensive unit tests for cross-mode history navigation (40 tests) Fixes the bug where users couldnt navigate through input history with up/down arrow keys after changing modes (entering/exiting feedback mode, bash mode, etc).
1 parent be34f79 commit 4ad692d

File tree

5 files changed

+760
-21
lines changed

5 files changed

+760
-21
lines changed

cli/src/chat.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ export const Chat = ({
317317
setForceFileOnlyMentions(true)
318318
}, [cursorPosition, inputValue, setInputValue])
319319

320-
const { saveToHistory, navigateUp, navigateDown } = useInputHistory(
320+
const { saveToHistory, navigateUp, navigateDown, resetHistoryNavigation } = useInputHistory(
321321
inputValue,
322322
setInputValue,
323323
{ inputMode, setInputMode },
@@ -747,7 +747,8 @@ export const Chat = ({
747747
lastEditDueToNav: false,
748748
})
749749
setInputFocused(true)
750-
}, [restoreSavedInput, setInputValue, setInputFocused])
750+
resetHistoryNavigation()
751+
}, [restoreSavedInput, setInputValue, setInputFocused, resetHistoryNavigation])
751752

752753
const handleCloseFeedback = useCallback(() => {
753754
closeFeedback()

cli/src/components/chat-input-bar.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export const ChatInputBar = ({
117117
const { submitAnswers, skip } = useAskUserBridge()
118118
const [askUserTitle] = React.useState(' Some questions for you ')
119119

120-
// Shared key intercept handler for suggestion menu navigation
120+
// Shared key intercept handler for suggestion menu navigation and history navigation
121121
const handleKeyIntercept = useEvent(
122122
(key: {
123123
name?: string
@@ -126,32 +126,36 @@ export const ChatInputBar = ({
126126
meta?: boolean
127127
option?: boolean
128128
}) => {
129-
// Intercept navigation keys when suggestion menu is active
130-
// The useChatKeyboard hook will handle menu selection/navigation
131-
const hasSuggestions = hasSlashSuggestions || hasMentionSuggestions
132-
if (!hasSuggestions) return false
133-
134129
const isPlainEnter =
135130
(key.name === 'return' || key.name === 'enter') &&
136131
!key.shift &&
137132
!key.ctrl &&
138133
!key.meta &&
139134
!key.option
140135
const isTab = key.name === 'tab' && !key.ctrl && !key.meta && !key.option
141-
const isUpDown =
142-
(key.name === 'up' || key.name === 'down') &&
143-
!key.ctrl &&
144-
!key.meta &&
145-
!key.option
136+
const isUp = key.name === 'up' && !key.ctrl && !key.meta && !key.option
137+
const isDown = key.name === 'down' && !key.ctrl && !key.meta && !key.option
138+
const isUpDown = isUp || isDown
146139

147-
// Don't intercept Up/Down when user is navigating history
148-
if (isUpDown && lastEditDueToNav) {
149-
return false
140+
const hasSuggestions = hasSlashSuggestions || hasMentionSuggestions
141+
if (hasSuggestions) {
142+
if (isUpDown && lastEditDueToNav) {
143+
return true
144+
}
145+
if (isPlainEnter || isTab || isUpDown) {
146+
return true
147+
}
150148
}
151149

152-
if (isPlainEnter || isTab || isUpDown) {
150+
const historyUpEnabled = lastEditDueToNav || cursorPosition === 0
151+
const historyDownEnabled = lastEditDueToNav || cursorPosition === inputValue.length
152+
if (isUp && historyUpEnabled) {
153153
return true
154154
}
155+
if (isDown && historyDownEnabled) {
156+
return true
157+
}
158+
155159
return false
156160
},
157161
)

0 commit comments

Comments
 (0)