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

pull/1850/head
Blaž Hrastnik 2 years ago
parent 7909d6f05e
commit a7ee9f74f7
No known key found for this signature in database
GPG Key ID: 1238B9C4AD889640

@ -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
KeymapResultKind::Cancelled(self.state.drain(..).collect()), return KeymapResult::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"
); );

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

Loading…
Cancel
Save