refactor(keymap): add Char key fallback and remove unused SHIFT binding

Improve keymap lookup for Char keys by adding fallback to NONE modifiers.
Terminals vary in whether they send SHIFT for uppercase/symbol characters,
so we now retry without modifiers when an exact match fails.

Also removed the unused shift variable and updated key bindings to use
NONE modifiers instead of SHIFT for consistency.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
This commit is contained in:
Edward Langley
2026-04-04 18:37:43 -07:00
parent 89fdb27d6c
commit 0f1de6ba58

View File

@ -133,9 +133,21 @@ impl Keymap {
}
/// Look up the binding for a key.
/// For Char keys, if exact (key, mods) match fails, retries with NONE
/// modifiers since terminals vary in whether they send SHIFT for
/// uppercase/symbol characters.
pub fn lookup(&self, key: KeyCode, mods: KeyModifiers) -> Option<&Binding> {
self.bindings
.get(&KeyPattern::Key(key, mods))
.or_else(|| {
// Retry Char keys without modifiers (shift is implicit in the char)
if matches!(key, KeyCode::Char(_)) && mods != KeyModifiers::NONE {
self.bindings
.get(&KeyPattern::Key(key, KeyModifiers::NONE))
} else {
None
}
})
.or_else(|| {
if matches!(key, KeyCode::Char(_)) {
self.bindings.get(&KeyPattern::AnyChar)
@ -222,7 +234,6 @@ impl KeymapSet {
let mut set = Self::new(registry);
let none = KeyModifiers::NONE;
let ctrl = KeyModifiers::CONTROL;
let shift = KeyModifiers::SHIFT;
// ── Normal mode ──────────────────────────────────────────────────
let mut normal = Keymap::new();
@ -251,9 +262,9 @@ impl KeymapSet {
}
// Jump to boundaries
normal.bind(KeyCode::Char('G'), shift, "jump-last-row");
normal.bind(KeyCode::Char('G'), none, "jump-last-row");
normal.bind(KeyCode::Char('0'), none, "jump-first-col");
normal.bind(KeyCode::Char('$'), shift, "jump-last-col");
normal.bind(KeyCode::Char('$'), none, "jump-last-col");
// Scroll
normal.bind_args(KeyCode::Char('d'), ctrl, "scroll-rows", vec!["5".into()]);
@ -270,7 +281,7 @@ impl KeymapSet {
normal.bind(KeyCode::Char('q'), ctrl, "force-quit");
normal.bind_args(
KeyCode::Char(':'),
shift,
none,
"enter-mode",
vec!["command".into()],
);
@ -278,24 +289,24 @@ impl KeymapSet {
normal.bind(KeyCode::Char('s'), ctrl, "save");
normal.bind(KeyCode::F(1), none, "enter-mode");
normal.bind_args(KeyCode::F(1), none, "enter-mode", vec!["help".into()]);
normal.bind_args(KeyCode::Char('?'), shift, "enter-mode", vec!["help".into()]);
normal.bind_args(KeyCode::Char('?'), none, "enter-mode", vec!["help".into()]);
// Panel toggles
normal.bind_args(
KeyCode::Char('F'),
shift,
none,
"toggle-panel-and-focus",
vec!["formula".into()],
);
normal.bind_args(
KeyCode::Char('C'),
shift,
none,
"toggle-panel-and-focus",
vec!["category".into()],
);
normal.bind_args(
KeyCode::Char('V'),
shift,
none,
"toggle-panel-and-focus",
vec!["view".into()],
);
@ -332,7 +343,7 @@ impl KeymapSet {
"search-navigate",
vec!["forward".into()],
);
normal.bind(KeyCode::Char('N'), shift, "search-or-category-add");
normal.bind(KeyCode::Char('N'), none, "search-or-category-add");
// Page navigation
normal.bind(KeyCode::Char(']'), none, "page-next");
@ -340,10 +351,10 @@ impl KeymapSet {
// Group / hide
normal.bind(KeyCode::Char('z'), none, "toggle-group-under-cursor");
normal.bind(KeyCode::Char('H'), shift, "hide-selected-row-item");
normal.bind(KeyCode::Char('H'), none, "hide-selected-row-item");
// Tile select
normal.bind(KeyCode::Char('T'), shift, "enter-tile-select");
normal.bind(KeyCode::Char('T'), none, "enter-tile-select");
normal.bind(KeyCode::Left, ctrl, "enter-tile-select");
normal.bind(KeyCode::Right, ctrl, "enter-tile-select");
normal.bind(KeyCode::Up, ctrl, "enter-tile-select");
@ -360,8 +371,8 @@ impl KeymapSet {
normal.bind_prefix(KeyCode::Char('y'), none, Arc::new(y_map));
let mut z_map = Keymap::new();
z_map.bind(KeyCode::Char('Z'), shift, "save-and-quit");
normal.bind_prefix(KeyCode::Char('Z'), shift, Arc::new(z_map));
z_map.bind(KeyCode::Char('Z'), none, "save-and-quit");
normal.bind_prefix(KeyCode::Char('Z'), none, Arc::new(z_map));
set.insert(ModeKey::Normal, Arc::new(normal));