Add support for labels on typable commands

pull/3958/head
Matthew Cheely 2022-09-23 23:03:56 -04:00
parent 08e0616a4c
commit a7f603361a
2 changed files with 63 additions and 3 deletions

View File

@ -207,6 +207,44 @@ mod tests {
); );
} }
#[test]
fn parsing_typable_commands() {
use crate::keymap;
use crate::keymap::MappableCommand;
use helix_view::document::Mode;
use helix_view::input::KeyEvent;
use std::str::FromStr;
let sample_keymaps = r#"
[keys.normal]
o = { label = "Edit Config", command = ":open ~/.config" }
c = ":buffer-close"
"#;
let config = toml::from_str::<Config>(sample_keymaps).unwrap();
let tree = config.keys.get(&Mode::Normal).unwrap().root();
if let keymap::KeyTrie::Node(node) = tree {
let open_node = node.get(&KeyEvent::from_str("o").unwrap()).unwrap();
if let keymap::KeyTrie::Leaf(MappableCommand::Typable { doc, .. }) = open_node {
assert_eq!(doc, "Edit Config");
} else {
panic!("Edit Config did not parse to typable command");
}
let close_node = node.get(&KeyEvent::from_str("c").unwrap()).unwrap();
if let keymap::KeyTrie::Leaf(MappableCommand::Typable { doc, .. }) = close_node {
assert_eq!(doc, ":buffer-close []");
} else {
panic!(":buffer-close command did not parse to typable command");
}
} else {
panic!("Config did not parse to trie");
}
}
#[test] #[test]
fn keys_resolve_to_correct_defaults() { fn keys_resolve_to_correct_defaults() {
// From serde default // From serde default

View File

@ -197,13 +197,15 @@ impl<'de> serde::de::Visitor<'de> for KeyTrieVisitor {
where where
M: serde::de::MapAccess<'de>, M: serde::de::MapAccess<'de>,
{ {
let mut name = ""; let mut label = "";
let mut command = None;
let mut mapping = HashMap::new(); let mut mapping = HashMap::new();
let mut order = Vec::new(); let mut order = Vec::new();
while let Some(key) = map.next_key::<&str>()? { while let Some(key) = map.next_key::<&str>()? {
match key { match key {
"label" => name = map.next_value::<&str>()?, "label" => label = map.next_value::<&str>()?,
"command" => command = Some(map.next_value::<MappableCommand>()?),
_ => { _ => {
let key_event = key.parse::<KeyEvent>().map_err(serde::de::Error::custom)?; let key_event = key.parse::<KeyEvent>().map_err(serde::de::Error::custom)?;
let key_trie = map.next_value::<KeyTrie>()?; let key_trie = map.next_value::<KeyTrie>()?;
@ -212,7 +214,27 @@ impl<'de> serde::de::Visitor<'de> for KeyTrieVisitor {
} }
} }
} }
Ok(KeyTrie::Node(KeyTrieNode::new(name, mapping, order)))
match command {
None => Ok(KeyTrie::Node(KeyTrieNode::new(label, mapping, order))),
Some(cmd) => {
if label.is_empty() {
Ok(KeyTrie::Leaf(cmd))
} else {
match cmd {
MappableCommand::Typable { name, args, .. } => {
Ok(MappableCommand::Typable {
name,
args,
doc: label.to_string(),
})
.map(KeyTrie::Leaf)
}
MappableCommand::Static { .. } => Ok(KeyTrie::Leaf(cmd)),
}
}
}
}
} }
} }