diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2023-08-29 10:16:53 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2023-08-29 10:16:53 -0400 |
commit | 31beaabe6b2cf4119aacae6c1722cdc1e5ba2f5b (patch) | |
tree | 095ec193999ac9ad3494a2abf039ff1dc7da00d2 /src/config/keymap/keymapping.rs | |
parent | 40ab1b0125c86b6554f2a23d90053c805d7a857a (diff) |
command chaining support
- breaks existing keymap configs
-`command` field is renamed to `commands`
- now an array instead of a single string
Diffstat (limited to 'src/config/keymap/keymapping.rs')
-rw-r--r-- | src/config/keymap/keymapping.rs | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/src/config/keymap/keymapping.rs b/src/config/keymap/keymapping.rs index 0b3e122..33c7407 100644 --- a/src/config/keymap/keymapping.rs +++ b/src/config/keymap/keymapping.rs @@ -8,7 +8,7 @@ use termion::event::Event; use crate::config::{parse_config_or_default, TomlConfigFile}; use crate::error::JoshutoResult; -use crate::key_command::{AppCommand, Command, CommandKeybind}; +use crate::key_command::{Command, CommandKeybind}; use crate::traits::ToString; use crate::util::keyparse::str_to_event; @@ -20,9 +20,9 @@ enum KeymapError { #[derive(Clone, Debug, Deserialize)] struct CommandKeymap { - pub command: String, - pub description: Option<String>, pub keys: Vec<String>, + pub commands: Vec<String>, + pub description: Option<String>, } #[derive(Clone, Debug, Deserialize)] @@ -63,38 +63,53 @@ impl AppKeyMapping { } } -fn vec_to_map(vec: &[CommandKeymap]) -> HashMap<Event, CommandKeybind> { +fn command_keymaps_vec_to_map(keymaps: &[CommandKeymap]) -> HashMap<Event, CommandKeybind> { let mut hashmap = HashMap::new(); - for m in vec { - match Command::from_str(m.command.as_str()) { - Ok(command) => { - let events: Vec<Event> = m - .keys - .iter() - .filter_map(|s| str_to_event(s.as_str())) - .collect(); - - if events.len() != m.keys.len() { - eprintln!("Failed to parse events: {:?}", m.keys); - continue; + for keymap in keymaps { + if keymap.commands.is_empty() { + eprintln!("Keymap `commands` cannot be empty"); + continue; + } + let commands: Vec<Command> = keymap + .commands + .iter() + .filter_map(|cmd_str| match Command::from_str(cmd_str) { + Ok(s) => Some(s), + Err(err) => { + eprintln!("Keymap error: {}", err); + None } + }) + .collect(); + + if commands.len() != keymap.commands.len() { + eprintln!("Failed to parse commands: {:?}", keymap.commands); + continue; + } + + let key_events: Vec<Event> = keymap + .keys + .iter() + .filter_map(|s| str_to_event(s.as_str())) + .collect(); + + if key_events.len() != keymap.keys.len() { + eprintln!("Failed to parse keys: {:?}", keymap.keys); + continue; + } - let command_str = command.command(); - let command_description = m.description.to_owned(); - let result = insert_keycommand(&mut hashmap, command, command_description, &events); - match result { - Ok(_) => {} - Err(e) => match e { - KeymapError::Conflict => { - let events_str: Vec<String> = - events.iter().map(|e| e.to_string()).collect(); - eprintln!("Error: Ambiguous Keymapping: Multiple commands mapped to key sequence {:?} {}", events_str, command_str); - } - }, + let command_description = keymap.description.to_owned(); + if let Err(err) = + insert_keycommand(&mut hashmap, commands, command_description, &key_events) + { + match err { + KeymapError::Conflict => { + let events_str: Vec<String> = + key_events.iter().map(|e| e.to_string()).collect(); + eprintln!("Error: Ambiguous Keymapping: Multiple commands mapped to key sequence {:?} {:?}", events_str, keymap.commands); } } - Err(e) => eprintln!("Keymap error: {}", e), } } hashmap @@ -103,9 +118,9 @@ fn vec_to_map(vec: &[CommandKeymap]) -> HashMap<Event, CommandKeybind> { impl From<AppKeyMappingRaw> for AppKeyMapping { fn from(raw: AppKeyMappingRaw) -> Self { let mut keymaps = Self::new(); - keymaps.default_view = vec_to_map(&raw.default_view.keymap); - keymaps.task_view = vec_to_map(&raw.task_view.keymap); - keymaps.help_view = vec_to_map(&raw.help_view.keymap); + keymaps.default_view = command_keymaps_vec_to_map(&raw.default_view.keymap); + keymaps.task_view = command_keymaps_vec_to_map(&raw.task_view.keymap); + keymaps.help_view = command_keymaps_vec_to_map(&raw.help_view.keymap); keymaps } } @@ -126,7 +141,7 @@ impl std::default::Default for AppKeyMapping { fn insert_keycommand( keymap: &mut KeyMapping, - keycommand: Command, + commands: Vec<Command>, description: Option<String>, events: &[Event], ) -> Result<(), KeymapError> { @@ -140,7 +155,7 @@ fn insert_keycommand( match keymap.entry(event) { Entry::Occupied(_) => return Err(KeymapError::Conflict), Entry::Vacant(entry) => entry.insert(CommandKeybind::SimpleKeybind { - command: keycommand, + commands, description, }), }; @@ -150,13 +165,13 @@ fn insert_keycommand( match keymap.entry(event) { Entry::Occupied(mut entry) => match entry.get_mut() { CommandKeybind::CompositeKeybind(ref mut m) => { - insert_keycommand(m, keycommand, description, &events[1..]) + insert_keycommand(m, commands, description, &events[1..]) } _ => Err(KeymapError::Conflict), }, Entry::Vacant(entry) => { let mut new_map = KeyMapping::new(); - let result = insert_keycommand(&mut new_map, keycommand, description, &events[1..]); + let result = insert_keycommand(&mut new_map, commands, description, &events[1..]); if result.is_ok() { let composite_command = CommandKeybind::CompositeKeybind(new_map); entry.insert(composite_command); |