mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat(tui): allow function keys through f24 in keymaps (#25329)
## Why Closes #25006. `tui.keymap` currently rejects `F13` even though Codex's terminal event layer can report higher function keys. This prevents users from using common remappings such as Caps Lock to `F13`. ## What Changed - Define a shared portable upper bound of `F24` for stored TUI keybindings. - Accept `f13` through `f24` in config normalization and runtime parsing. - Allow `/keymap` capture to persist `F13` through `F24`. - Update the unsupported-function-key error and add boundary tests for `F13`, `F24`, and `F25`. ## How to Test 1. Add a binding such as: ```toml [tui.keymap.global] open_transcript = "f13" ``` 2. Start Codex and press the remapped `F13` key. 3. Confirm Codex loads the config without the previous `F1 through F12` error and the action runs. 4. Open `/keymap`, capture `F13` for an action, and confirm the saved binding is `f13`. 5. As a regression check, try to capture `F25` and confirm Codex reports that only `F1` through `F24` can be stored. Targeted tests: - `just test -p codex-config` - `just test -p codex-tui function_keys` Full `just test -p codex-tui` completed with 2,752 passing tests, 4 skipped tests, and two unrelated guardian feature-flag failures: - `app::tests::update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default` - `app::tests::update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`
This commit is contained in:
@@ -33,6 +33,7 @@ pub(crate) use picker::build_keymap_picker_params_with_filter;
|
||||
|
||||
use codex_config::types::KeybindingSpec;
|
||||
use codex_config::types::KeybindingsSpec;
|
||||
use codex_config::types::MAX_FUNCTION_KEY;
|
||||
use codex_config::types::TuiKeymap;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
@@ -737,11 +738,11 @@ fn key_parts_to_config_key_spec(
|
||||
KeyCode::End => "end".to_string(),
|
||||
KeyCode::PageUp => "page-up".to_string(),
|
||||
KeyCode::PageDown => "page-down".to_string(),
|
||||
KeyCode::F(number) if (1..=12).contains(&number) => format!("f{number}"),
|
||||
KeyCode::F(number) if (1..=MAX_FUNCTION_KEY).contains(&number) => format!("f{number}"),
|
||||
KeyCode::F(_) => {
|
||||
return Err(
|
||||
"Only function keys F1 through F12 can be stored in `tui.keymap`.".to_string(),
|
||||
);
|
||||
return Err(format!(
|
||||
"Only function keys F1 through F{MAX_FUNCTION_KEY} can be stored in `tui.keymap`."
|
||||
));
|
||||
}
|
||||
KeyCode::Char(' ') => "space".to_string(),
|
||||
KeyCode::Char(mut ch) => {
|
||||
@@ -1610,6 +1611,22 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_capture_serializes_function_keys_through_f24() {
|
||||
assert_eq!(
|
||||
key_event_to_config_key_spec(KeyEvent::from(KeyCode::F(13))),
|
||||
Ok("f13".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
key_event_to_config_key_spec(KeyEvent::from(KeyCode::F(24))),
|
||||
Ok("f24".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
key_event_to_config_key_spec(KeyEvent::from(KeyCode::F(25))),
|
||||
Err("Only function keys F1 through F24 can be stored in `tui.keymap`.".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_capture_serializes_c0_control_chars_as_ctrl_bindings() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user