From 4a3e9ed88d0d4a2624df8dfc97b600aac9b28b3e Mon Sep 17 00:00:00 2001 From: Takuto Yuki Date: Tue, 9 Dec 2025 04:21:15 +0900 Subject: [PATCH] fix(tui): add missing Ctrl+n/Ctrl+p support to ListSelectionView (#7629) ## Summary Extend Ctrl+n/Ctrl+p navigation support to selection popups (model picker, approval mode, etc.) This is a follow-up to #7530, which added Ctrl+n/Ctrl+p navigation to the textarea. The same keybindings were missing from `ListSelectionView`, causing inconsistent behavior when navigating selection popups. ## Related - #7530 - feat(tui): map Ctrl-P/N to arrow navigation in textarea ## Changes - Added Ctrl+n as alternative to Down arrow in selection popups - Added Ctrl+p as alternative to Up arrow in selection popups - Added unit tests for the new keybindings ## Test Plan - [x] `cargo test -p codex-tui list_selection_view` - all tests pass - [x] Manual testing: verified Ctrl+n/p navigation works in model selection popup --------- Co-authored-by: Eric Traut --- .../src/bottom_pane/list_selection_view.rs | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/codex-rs/tui/src/bottom_pane/list_selection_view.rs b/codex-rs/tui/src/bottom_pane/list_selection_view.rs index b58524185..26a32a42e 100644 --- a/codex-rs/tui/src/bottom_pane/list_selection_view.rs +++ b/codex-rs/tui/src/bottom_pane/list_selection_view.rs @@ -268,13 +268,36 @@ impl ListSelectionView { impl BottomPaneView for ListSelectionView { fn handle_key_event(&mut self, key_event: KeyEvent) { match key_event { + // Some terminals (or configurations) send Control key chords as + // C0 control characters without reporting the CONTROL modifier. + // Handle fallbacks for Ctrl-P/N here so navigation works everywhere. KeyEvent { code: KeyCode::Up, .. - } => self.move_up(), + } + | KeyEvent { + code: KeyCode::Char('p'), + modifiers: KeyModifiers::CONTROL, + .. + } + | KeyEvent { + code: KeyCode::Char('\u{0010}'), + modifiers: KeyModifiers::NONE, + .. + } /* ^P */ => self.move_up(), KeyEvent { code: KeyCode::Down, .. - } => self.move_down(), + } + | KeyEvent { + code: KeyCode::Char('n'), + modifiers: KeyModifiers::CONTROL, + .. + } + | KeyEvent { + code: KeyCode::Char('\u{000e}'), + modifiers: KeyModifiers::NONE, + .. + } /* ^N */ => self.move_down(), KeyEvent { code: KeyCode::Backspace, ..