// src/input/leader.rs use crate::config::binds::config::Config; use crate::config::binds::key_sequences::parse_binding; use crossterm::event::KeyCode; /// Collect leader (= space-prefixed) bindings from *all* binding maps fn leader_bindings<'a>(config: &'a Config) -> Vec<(&'a str, Vec)> { let mut out = Vec::new(); // Include all keybinding maps, not just global let all_modes: Vec<&std::collections::HashMap>> = vec![ &config.keybindings.general, &config.keybindings.read_only, &config.keybindings.edit, &config.keybindings.highlight, &config.keybindings.command, &config.keybindings.common, &config.keybindings.global, ]; for mode in all_modes { for (action, bindings) in mode { for b in bindings { let parsed = parse_binding(b); if parsed.first().map(|pk| pk.code) == Some(KeyCode::Char(' ')) { let codes = parsed.into_iter().map(|pk| pk.code).collect::>(); out.push((action.as_str(), codes)); } } } } out } /// Is there any leader binding configured at all? pub fn leader_has_any_start(config: &Config) -> bool { leader_bindings(config) .iter() .any(|(_, seq)| seq.first() == Some(&KeyCode::Char(' '))) } /// Is `sequence` a prefix of any configured leader sequence? pub fn leader_is_prefix(config: &Config, sequence: &[KeyCode]) -> bool { if sequence.is_empty() || sequence[0] != KeyCode::Char(' ') { return false; } for (_, full) in leader_bindings(config) { if full.len() > sequence.len() && full.iter().zip(sequence.iter()).all(|(a, b)| a == b) { return true; } } false } /// Is `sequence` an exact leader match? If yes, return the action string. pub fn leader_match_action<'a>( config: &'a Config, sequence: &[KeyCode], ) -> Option<&'a str> { if sequence.is_empty() || sequence[0] != KeyCode::Char(' ') { return None; } for (action, full) in leader_bindings(config) { if full.len() == sequence.len() && full.iter().zip(sequence.iter()).all(|(a, b)| a == b) { return Some(action); } } None }