(e: KeyboardEvent)
| 1292 | |
| 1293 | // Handle keyboard input for behaviors not covered by keybindings |
| 1294 | const handleKeyDown = (e: KeyboardEvent): void => { |
| 1295 | // Handle right arrow to accept prompt suggestion ghost text |
| 1296 | if (e.key === 'right' && !isViewingTeammate) { |
| 1297 | const suggestionText = promptSuggestion.text; |
| 1298 | const suggestionShownAt = promptSuggestion.shownAt; |
| 1299 | if (suggestionText && suggestionShownAt > 0 && input === '') { |
| 1300 | markAccepted(); |
| 1301 | acceptSuggestionText(suggestionText); |
| 1302 | e.stopImmediatePropagation(); |
| 1303 | return; |
| 1304 | } |
| 1305 | } |
| 1306 | |
| 1307 | // Handle Tab key fallback behaviors when no autocomplete suggestions |
| 1308 | // Don't handle tab if shift is pressed (used for mode cycle) |
| 1309 | if (e.key === 'tab' && !e.shift) { |
| 1310 | // Skip if autocomplete is handling this (suggestions or ghost text exist) |
| 1311 | if (suggestions.length > 0 || effectiveGhostText) { |
| 1312 | return; |
| 1313 | } |
| 1314 | // Accept prompt suggestion if it exists in AppState |
| 1315 | const suggestionText = promptSuggestion.text; |
| 1316 | const suggestionShownAt = promptSuggestion.shownAt; |
| 1317 | if (suggestionText && suggestionShownAt > 0 && input === '' && !isViewingTeammate) { |
| 1318 | e.preventDefault(); |
| 1319 | markAccepted(); |
| 1320 | acceptSuggestionText(suggestionText); |
| 1321 | return; |
| 1322 | } |
| 1323 | // Remind user about thinking toggle shortcut if empty input |
| 1324 | if (input.trim() === '') { |
| 1325 | e.preventDefault(); |
| 1326 | addNotification({ |
| 1327 | key: 'thinking-toggle-hint', |
| 1328 | jsx: <Text dimColor> |
| 1329 | Use {thinkingToggleShortcut} to toggle thinking |
| 1330 | </Text>, |
| 1331 | priority: 'immediate', |
| 1332 | timeoutMs: 3000 |
| 1333 | }); |
| 1334 | } |
| 1335 | return; |
| 1336 | } |
| 1337 | |
| 1338 | // Only continue with navigation if we have suggestions |
| 1339 | if (suggestions.length === 0) return; |
| 1340 | |
| 1341 | // Handle Ctrl-N/P for navigation (arrows handled by keybindings) |
| 1342 | // Skip if we're in the middle of a chord sequence to allow chords like ctrl+f n |
| 1343 | const hasPendingChord = keybindingContext?.pendingChord != null; |
| 1344 | if (e.ctrl && e.key === 'n' && !hasPendingChord) { |
| 1345 | e.preventDefault(); |
| 1346 | handleAutocompleteNext(); |
| 1347 | return; |
| 1348 | } |
| 1349 | if (e.ctrl && e.key === 'p' && !hasPendingChord) { |
| 1350 | e.preventDefault(); |
| 1351 | handleAutocompletePrevious(); |
no test coverage detected