space commands here we go again
This commit is contained in:
74
client/src/input/leader.rs
Normal file
74
client/src/input/leader.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
// 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<KeyCode>)> {
|
||||
let mut out = Vec::new();
|
||||
|
||||
// Include all keybinding maps, not just global
|
||||
let all_modes: Vec<&std::collections::HashMap<String, Vec<String>>> = 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::<Vec<_>>();
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user