mirror of
https://github.com/openai/codex.git
synced 2026-09-15 12:08:01 +00:00
test(tui): add runtime keymap resolver characterization suite
Introduce the TUI runtime keymap resolver and keybinding matching helpers with a dedicated unit-test suite. This commit is additive only: it adds resolution logic, conflict validation, parser coverage, and documented macros without wiring input handlers to the new runtime map yet.
This commit is contained in:
@@ -15,7 +15,7 @@ const ALT_PREFIX: &str = "alt + ";
|
||||
const CTRL_PREFIX: &str = "ctrl + ";
|
||||
const SHIFT_PREFIX: &str = "shift + ";
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub(crate) struct KeyBinding {
|
||||
key: KeyCode,
|
||||
modifiers: KeyModifiers,
|
||||
@@ -31,6 +31,22 @@ impl KeyBinding {
|
||||
&& self.modifiers == event.modifiers
|
||||
&& (event.kind == KeyEventKind::Press || event.kind == KeyEventKind::Repeat)
|
||||
}
|
||||
|
||||
pub(crate) const fn parts(&self) -> (KeyCode, KeyModifiers) {
|
||||
(self.key, self.modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Matching helpers for one action's keybinding set.
|
||||
pub(crate) trait KeyBindingListExt {
|
||||
/// True when any binding in this set matches `event`.
|
||||
fn is_pressed(&self, event: KeyEvent) -> bool;
|
||||
}
|
||||
|
||||
impl KeyBindingListExt for [KeyBinding] {
|
||||
fn is_pressed(&self, event: KeyEvent) -> bool {
|
||||
self.iter().any(|binding| binding.is_press(event))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn plain(key: KeyCode) -> KeyBinding {
|
||||
@@ -110,3 +126,60 @@ pub(crate) fn is_altgr(mods: KeyModifiers) -> bool {
|
||||
pub(crate) fn is_altgr(_mods: KeyModifiers) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn is_press_accepts_press_and_repeat_but_rejects_release() {
|
||||
let binding = ctrl(KeyCode::Char('k'));
|
||||
let press = KeyEvent::new(KeyCode::Char('k'), KeyModifiers::CONTROL);
|
||||
let repeat = KeyEvent {
|
||||
kind: KeyEventKind::Repeat,
|
||||
..press
|
||||
};
|
||||
let release = KeyEvent {
|
||||
kind: KeyEventKind::Release,
|
||||
..press
|
||||
};
|
||||
let wrong_modifiers = KeyEvent::new(KeyCode::Char('k'), KeyModifiers::NONE);
|
||||
|
||||
assert!(binding.is_press(press));
|
||||
assert!(binding.is_press(repeat));
|
||||
assert!(!binding.is_press(release));
|
||||
assert!(!binding.is_press(wrong_modifiers));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keybinding_list_ext_matches_any_binding() {
|
||||
let bindings = [plain(KeyCode::Char('a')), ctrl(KeyCode::Char('b'))];
|
||||
|
||||
assert!(bindings.is_pressed(KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE)));
|
||||
assert!(bindings.is_pressed(KeyEvent::new(KeyCode::Char('b'), KeyModifiers::CONTROL)));
|
||||
assert!(!bindings.is_pressed(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::NONE)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_alt_sets_both_modifiers() {
|
||||
assert_eq!(
|
||||
ctrl_alt(KeyCode::Char('v')).parts(),
|
||||
(
|
||||
KeyCode::Char('v'),
|
||||
KeyModifiers::CONTROL | KeyModifiers::ALT
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has_ctrl_or_alt_checks_supported_modifier_combinations() {
|
||||
assert!(!has_ctrl_or_alt(KeyModifiers::NONE));
|
||||
assert!(has_ctrl_or_alt(KeyModifiers::CONTROL));
|
||||
assert!(has_ctrl_or_alt(KeyModifiers::ALT));
|
||||
|
||||
#[cfg(windows)]
|
||||
assert!(!has_ctrl_or_alt(KeyModifiers::CONTROL | KeyModifiers::ALT));
|
||||
#[cfg(not(windows))]
|
||||
assert!(has_ctrl_or_alt(KeyModifiers::CONTROL | KeyModifiers::ALT));
|
||||
}
|
||||
}
|
||||
|
||||
1128
codex-rs/tui/src/keymap.rs
Normal file
1128
codex-rs/tui/src/keymap.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -80,6 +80,7 @@ mod get_git_diff;
|
||||
mod history_cell;
|
||||
pub mod insert_history;
|
||||
mod key_hint;
|
||||
mod keymap;
|
||||
pub mod live_wrap;
|
||||
mod markdown;
|
||||
mod markdown_render;
|
||||
|
||||
Reference in New Issue
Block a user