(key: Key)
| 317 | } |
| 318 | |
| 319 | function mapKey(key: Key): InputMapper { |
| 320 | switch (true) { |
| 321 | case key.escape: |
| 322 | return () => { |
| 323 | // Skip when a keybinding context (e.g. Autocomplete) owns escape. |
| 324 | // useKeybindings can't shield us via stopImmediatePropagation — |
| 325 | // BaseTextInput's useInput registers first (child effects fire |
| 326 | // before parent effects), so this handler has already run by the |
| 327 | // time the keybinding's handler stops propagation. |
| 328 | if (disableEscapeDoublePress) return cursor |
| 329 | handleEscape() |
| 330 | // Return the current cursor unchanged - handleEscape manages state internally |
| 331 | return cursor |
| 332 | } |
| 333 | case key.leftArrow && (key.ctrl || key.meta || key.fn): |
| 334 | return () => cursor.prevWord() |
| 335 | case key.rightArrow && (key.ctrl || key.meta || key.fn): |
| 336 | return () => cursor.nextWord() |
| 337 | case key.backspace: |
| 338 | return key.meta || key.ctrl |
| 339 | ? killWordBefore |
| 340 | : () => cursor.deleteTokenBefore() ?? cursor.backspace() |
| 341 | case key.delete: |
| 342 | return key.meta ? killToLineEnd : () => cursor.del() |
| 343 | case key.ctrl: |
| 344 | return handleCtrl |
| 345 | case key.home: |
| 346 | return () => cursor.startOfLine() |
| 347 | case key.end: |
| 348 | return () => cursor.endOfLine() |
| 349 | case key.pageDown: |
| 350 | // In fullscreen mode, PgUp/PgDn scroll the message viewport instead |
| 351 | // of moving the cursor — no-op here, ScrollKeybindingHandler handles it. |
| 352 | if (isFullscreenEnvEnabled()) { |
| 353 | return NOOP_HANDLER |
| 354 | } |
| 355 | return () => cursor.endOfLine() |
| 356 | case key.pageUp: |
| 357 | if (isFullscreenEnvEnabled()) { |
| 358 | return NOOP_HANDLER |
| 359 | } |
| 360 | return () => cursor.startOfLine() |
| 361 | case key.wheelUp: |
| 362 | case key.wheelDown: |
| 363 | // Mouse wheel events only exist when fullscreen mouse tracking is on. |
| 364 | // ScrollKeybindingHandler handles them; no-op here to avoid inserting |
| 365 | // the raw SGR sequence as text. |
| 366 | return NOOP_HANDLER |
| 367 | case key.return: |
| 368 | // Must come before key.meta so Option+Return inserts newline |
| 369 | return () => handleEnter(key) |
| 370 | case key.meta: |
| 371 | return handleMeta |
| 372 | case key.tab: |
| 373 | return () => cursor |
| 374 | case key.upArrow && !key.shift: |
| 375 | return upOrHistoryUp |
| 376 | case key.downArrow && !key.shift: |
no test coverage detected