diff --git a/codex-rs/tui/src/bottom_pane/textarea.rs b/codex-rs/tui/src/bottom_pane/textarea.rs index d1b45675..dabc276a 100644 --- a/codex-rs/tui/src/bottom_pane/textarea.rs +++ b/codex-rs/tui/src/bottom_pane/textarea.rs @@ -295,6 +295,20 @@ impl TextArea { } => { self.move_cursor_right(); } + KeyEvent { + code: KeyCode::Char('b'), + modifiers: KeyModifiers::CONTROL, + .. + } => { + self.move_cursor_left(); + } + KeyEvent { + code: KeyCode::Char('f'), + modifiers: KeyModifiers::CONTROL, + .. + } => { + self.move_cursor_right(); + } // Some terminals send Alt+Arrow for word-wise movement: // Option/Left -> Alt+Left (previous word start) // Option/Right -> Alt+Right (next word end) @@ -908,6 +922,22 @@ mod tests { assert_eq!(t.cursor(), t.text().len()); } + #[test] + fn control_b_and_f_move_cursor() { + use crossterm::event::KeyCode; + use crossterm::event::KeyEvent; + use crossterm::event::KeyModifiers; + + let mut t = ta_with("abcd"); + t.set_cursor(1); + + t.input(KeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL)); + assert_eq!(t.cursor(), 2); + + t.input(KeyEvent::new(KeyCode::Char('b'), KeyModifiers::CONTROL)); + assert_eq!(t.cursor(), 1); + } + #[test] fn cursor_vertical_movement_across_lines_and_bounds() { let mut t = ta_with("short\nloooooooooong\nmid");