No need for KeymapResult anymore since we can query .sticky()

This commit is contained in:
Blaž Hrastnik 2022-03-20 15:55:11 +09:00
parent 7909d6f05e
commit a7ee9f74f7
No known key found for this signature in database
GPG key ID: 1238B9C4AD889640
2 changed files with 31 additions and 57 deletions

View file

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

View file

@ -2,7 +2,7 @@ use crate::{
commands,
compositor::{Component, Context, EventResult},
key,
keymap::{KeymapResult, KeymapResultKind, Keymaps},
keymap::{KeymapResult, Keymaps},
ui::{Completion, ProgressSpinners},
};
@ -694,7 +694,7 @@ impl EditorView {
/// Handle events by looking them up in `self.keymaps`. Returns None
/// if event was handled (a command was executed or a subkeymap was
/// activated). Only KeymapResultKind::{NotFound, Cancelled} is returned
/// activated). Only KeymapResult::{NotFound, Cancelled} is returned
/// otherwise.
fn handle_keymap_event(
&mut self,
@ -704,36 +704,36 @@ impl EditorView {
) -> Option<KeymapResult> {
cxt.editor.autoinfo = None;
let key_result = self.keymaps.get(mode, event);
cxt.editor.autoinfo = key_result.sticky.map(|node| node.infobox());
cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
match &key_result.kind {
KeymapResultKind::Matched(command) => command.execute(cxt),
KeymapResultKind::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()),
KeymapResultKind::MatchedSequence(commands) => {
match &key_result {
KeymapResult::Matched(command) => command.execute(cxt),
KeymapResult::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()),
KeymapResult::MatchedSequence(commands) => {
for command in commands {
command.execute(cxt);
}
}
KeymapResultKind::NotFound | KeymapResultKind::Cancelled(_) => return Some(key_result),
KeymapResult::NotFound | KeymapResult::Cancelled(_) => return Some(key_result),
}
None
}
fn insert_mode(&mut self, cx: &mut commands::Context, event: KeyEvent) {
if let Some(keyresult) = self.handle_keymap_event(Mode::Insert, cx, event) {
match keyresult.kind {
KeymapResultKind::NotFound => {
match keyresult {
KeymapResult::NotFound => {
if let Some(ch) = event.char() {
commands::insert::insert_char(cx, ch)
}
}
KeymapResultKind::Cancelled(pending) => {
KeymapResult::Cancelled(pending) => {
for ev in pending {
match ev.char() {
Some(ch) => commands::insert::insert_char(cx, ch),
None => {
if let KeymapResultKind::Matched(command) =
self.keymaps.get(Mode::Insert, ev).kind
if let KeymapResult::Matched(command) =
self.keymaps.get(Mode::Insert, ev)
{
command.execute(cx);
}
@ -1182,8 +1182,8 @@ impl Component for EditorView {
// how we entered insert mode is important, and we should track that so
// we can repeat the side effect.
self.last_insert.0 = match self.keymaps.get(mode, key).kind {
KeymapResultKind::Matched(command) => command,
self.last_insert.0 = match self.keymaps.get(mode, key) {
KeymapResult::Matched(command) => command,
// FIXME: insert mode can only be entered through single KeyCodes
_ => unimplemented!(),
};