feat(keymap): add AnyChar pattern and new mode variants
Add AnyChar key pattern for text-entry modes that matches any Char key. Add new mode variants to ModeKey: FormulaPanel, CategoryPanel, ViewPanel, TileSelect, Editing, FormulaEdit, CategoryAdd, ItemAdd, ExportPrompt, CommandMode, and SearchMode. Update Keymap::lookup to fall back to AnyChar for Char keys. Update KeymapSet::get to accept search_mode parameter. Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
This commit is contained in:
@ -6,6 +6,7 @@ use crossterm::event::{KeyCode, KeyModifiers};
|
||||
|
||||
use crate::ui::app::AppMode;
|
||||
use crate::ui::effect::Effect;
|
||||
use crate::view::Axis;
|
||||
|
||||
use super::cmd::{self, Cmd, CmdContext};
|
||||
|
||||
@ -14,6 +15,9 @@ use super::cmd::{self, Cmd, CmdContext};
|
||||
pub enum KeyPattern {
|
||||
/// Single key with modifiers
|
||||
Key(KeyCode, KeyModifiers),
|
||||
/// Matches any Char key (for text-entry modes). The actual char
|
||||
/// is available in CmdContext::key_code.
|
||||
AnyChar,
|
||||
}
|
||||
|
||||
/// Identifies which mode a binding applies to.
|
||||
@ -22,14 +26,35 @@ pub enum KeyPattern {
|
||||
pub enum ModeKey {
|
||||
Normal,
|
||||
Help,
|
||||
// More modes can be added as we migrate handlers
|
||||
FormulaPanel,
|
||||
CategoryPanel,
|
||||
ViewPanel,
|
||||
TileSelect,
|
||||
Editing,
|
||||
FormulaEdit,
|
||||
CategoryAdd,
|
||||
ItemAdd,
|
||||
ExportPrompt,
|
||||
CommandMode,
|
||||
SearchMode,
|
||||
}
|
||||
|
||||
impl ModeKey {
|
||||
pub fn from_app_mode(mode: &AppMode) -> Option<Self> {
|
||||
pub fn from_app_mode(mode: &AppMode, search_mode: bool) -> Option<Self> {
|
||||
match mode {
|
||||
AppMode::Normal if search_mode => Some(ModeKey::SearchMode),
|
||||
AppMode::Normal => Some(ModeKey::Normal),
|
||||
AppMode::Help => Some(ModeKey::Help),
|
||||
AppMode::FormulaPanel => Some(ModeKey::FormulaPanel),
|
||||
AppMode::CategoryPanel => Some(ModeKey::CategoryPanel),
|
||||
AppMode::ViewPanel => Some(ModeKey::ViewPanel),
|
||||
AppMode::TileSelect => Some(ModeKey::TileSelect),
|
||||
AppMode::Editing { .. } => Some(ModeKey::Editing),
|
||||
AppMode::FormulaEdit { .. } => Some(ModeKey::FormulaEdit),
|
||||
AppMode::CategoryAdd { .. } => Some(ModeKey::CategoryAdd),
|
||||
AppMode::ItemAdd { .. } => Some(ModeKey::ItemAdd),
|
||||
AppMode::ExportPrompt { .. } => Some(ModeKey::ExportPrompt),
|
||||
AppMode::CommandMode { .. } => Some(ModeKey::CommandMode),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -77,9 +102,22 @@ impl Keymap {
|
||||
pub fn lookup(&self, key: KeyCode, mods: KeyModifiers) -> Option<&dyn Cmd> {
|
||||
self.bindings
|
||||
.get(&KeyPattern::Key(key, mods))
|
||||
.or_else(|| {
|
||||
// Fall back to AnyChar for text-entry modes
|
||||
if matches!(key, KeyCode::Char(_)) {
|
||||
self.bindings.get(&KeyPattern::AnyChar)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|c| c.as_ref())
|
||||
}
|
||||
|
||||
/// Bind a catch-all for any Char key (used for text-entry modes).
|
||||
pub fn bind_any_char(&mut self, cmd: impl Cmd + 'static) {
|
||||
self.bindings.insert(KeyPattern::AnyChar, Arc::new(cmd));
|
||||
}
|
||||
|
||||
/// Execute a keymap lookup and return effects, or None if no binding.
|
||||
pub fn dispatch(
|
||||
&self,
|
||||
@ -133,8 +171,8 @@ impl KeymapSet {
|
||||
}
|
||||
|
||||
/// Look up the root keymap for a given app mode.
|
||||
pub fn get(&self, mode: &AppMode) -> Option<&Arc<Keymap>> {
|
||||
let mode_key = ModeKey::from_app_mode(mode)?;
|
||||
pub fn get(&self, mode: &AppMode, search_mode: bool) -> Option<&Arc<Keymap>> {
|
||||
let mode_key = ModeKey::from_app_mode(mode, search_mode)?;
|
||||
self.mode_maps.get(&mode_key)
|
||||
}
|
||||
|
||||
@ -145,7 +183,7 @@ impl KeymapSet {
|
||||
key: KeyCode,
|
||||
mods: KeyModifiers,
|
||||
) -> Option<Vec<Box<dyn Effect>>> {
|
||||
let keymap = self.get(ctx.mode)?;
|
||||
let keymap = self.get(ctx.mode, ctx.search_mode)?;
|
||||
keymap.dispatch(ctx, key, mods)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user