|
|
@ -300,7 +300,7 @@ impl KeyTrie {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
pub enum KeymapResultKind {
|
|
|
|
pub enum KeymapResult {
|
|
|
|
/// Needs more keys to execute a command. Contains valid keys for next keystroke.
|
|
|
|
/// Needs more keys to execute a command. Contains valid keys for next keystroke.
|
|
|
|
Pending(KeyTrieNode),
|
|
|
|
Pending(KeyTrieNode),
|
|
|
|
Matched(MappableCommand),
|
|
|
|
Matched(MappableCommand),
|
|
|
@ -313,20 +313,6 @@ pub enum KeymapResultKind {
|
|
|
|
Cancelled(Vec<KeyEvent>),
|
|
|
|
Cancelled(Vec<KeyEvent>),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returned after looking up a key in [`Keymap`]. The `sticky` field has a
|
|
|
|
|
|
|
|
/// reference to the sticky node if one is currently active.
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
|
|
pub struct KeymapResult<'a> {
|
|
|
|
|
|
|
|
pub kind: KeymapResultKind,
|
|
|
|
|
|
|
|
pub sticky: Option<&'a KeyTrieNode>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> KeymapResult<'a> {
|
|
|
|
|
|
|
|
pub fn new(kind: KeymapResultKind, sticky: Option<&'a KeyTrieNode>) -> Self {
|
|
|
|
|
|
|
|
Self { kind, sticky }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
|
|
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Keymap {
|
|
|
|
pub struct Keymap {
|
|
|
@ -437,11 +423,8 @@ impl Keymaps {
|
|
|
|
|
|
|
|
|
|
|
|
if key!(Esc) == key {
|
|
|
|
if key!(Esc) == key {
|
|
|
|
if !self.state.is_empty() {
|
|
|
|
if !self.state.is_empty() {
|
|
|
|
return KeymapResult::new(
|
|
|
|
// Note that Esc is not included here
|
|
|
|
// Note that Esc is not included here
|
|
|
|
return KeymapResult::Cancelled(self.state.drain(..).collect());
|
|
|
|
KeymapResultKind::Cancelled(self.state.drain(..).collect()),
|
|
|
|
|
|
|
|
self.sticky(),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.sticky = None;
|
|
|
|
self.sticky = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -454,15 +437,12 @@ impl Keymaps {
|
|
|
|
|
|
|
|
|
|
|
|
let trie = match trie_node.search(&[*first]) {
|
|
|
|
let trie = match trie_node.search(&[*first]) {
|
|
|
|
Some(KeyTrie::Leaf(ref cmd)) => {
|
|
|
|
Some(KeyTrie::Leaf(ref cmd)) => {
|
|
|
|
return KeymapResult::new(KeymapResultKind::Matched(cmd.clone()), self.sticky())
|
|
|
|
return KeymapResult::Matched(cmd.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(KeyTrie::Sequence(ref cmds)) => {
|
|
|
|
Some(KeyTrie::Sequence(ref cmds)) => {
|
|
|
|
return KeymapResult::new(
|
|
|
|
return KeymapResult::MatchedSequence(cmds.clone());
|
|
|
|
KeymapResultKind::MatchedSequence(cmds.clone()),
|
|
|
|
|
|
|
|
self.sticky(),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => return KeymapResult::new(KeymapResultKind::NotFound, self.sticky()),
|
|
|
|
None => return KeymapResult::NotFound,
|
|
|
|
Some(t) => t,
|
|
|
|
Some(t) => t,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -473,23 +453,17 @@ impl Keymaps {
|
|
|
|
self.state.clear();
|
|
|
|
self.state.clear();
|
|
|
|
self.sticky = Some(map.clone());
|
|
|
|
self.sticky = Some(map.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeymapResult::new(KeymapResultKind::Pending(map.clone()), self.sticky())
|
|
|
|
KeymapResult::Pending(map.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(&KeyTrie::Leaf(ref cmd)) => {
|
|
|
|
Some(&KeyTrie::Leaf(ref cmd)) => {
|
|
|
|
self.state.clear();
|
|
|
|
self.state.clear();
|
|
|
|
return KeymapResult::new(KeymapResultKind::Matched(cmd.clone()), self.sticky());
|
|
|
|
KeymapResult::Matched(cmd.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(&KeyTrie::Sequence(ref cmds)) => {
|
|
|
|
Some(&KeyTrie::Sequence(ref cmds)) => {
|
|
|
|
self.state.clear();
|
|
|
|
self.state.clear();
|
|
|
|
KeymapResult::new(
|
|
|
|
KeymapResult::MatchedSequence(cmds.clone())
|
|
|
|
KeymapResultKind::MatchedSequence(cmds.clone()),
|
|
|
|
|
|
|
|
self.sticky(),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => KeymapResult::new(
|
|
|
|
None => KeymapResult::Cancelled(self.state.drain(..).collect()),
|
|
|
|
KeymapResultKind::Cancelled(self.state.drain(..).collect()),
|
|
|
|
|
|
|
|
self.sticky(),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -901,19 +875,19 @@ mod tests {
|
|
|
|
|
|
|
|
|
|
|
|
let keymap = &mut merged_config.keys;
|
|
|
|
let keymap = &mut merged_config.keys;
|
|
|
|
assert_eq!(
|
|
|
|
assert_eq!(
|
|
|
|
keymap.get(Mode::Normal, key!('i')).kind,
|
|
|
|
keymap.get(Mode::Normal, key!('i')),
|
|
|
|
KeymapResultKind::Matched(MappableCommand::normal_mode),
|
|
|
|
KeymapResult::Matched(MappableCommand::normal_mode),
|
|
|
|
"Leaf should replace leaf"
|
|
|
|
"Leaf should replace leaf"
|
|
|
|
);
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
assert_eq!(
|
|
|
|
keymap.get(Mode::Normal, key!('无')).kind,
|
|
|
|
keymap.get(Mode::Normal, key!('无')),
|
|
|
|
KeymapResultKind::Matched(MappableCommand::insert_mode),
|
|
|
|
KeymapResult::Matched(MappableCommand::insert_mode),
|
|
|
|
"New leaf should be present in merged keymap"
|
|
|
|
"New leaf should be present in merged keymap"
|
|
|
|
);
|
|
|
|
);
|
|
|
|
// Assumes that z is a node in the default keymap
|
|
|
|
// Assumes that z is a node in the default keymap
|
|
|
|
assert_eq!(
|
|
|
|
assert_eq!(
|
|
|
|
keymap.get(Mode::Normal, key!('z')).kind,
|
|
|
|
keymap.get(Mode::Normal, key!('z')),
|
|
|
|
KeymapResultKind::Matched(MappableCommand::jump_backward),
|
|
|
|
KeymapResult::Matched(MappableCommand::jump_backward),
|
|
|
|
"Leaf should replace node"
|
|
|
|
"Leaf should replace node"
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|