No need for KeymapResult anymore since we can query .sticky()
This commit is contained in:
parent
7909d6f05e
commit
a7ee9f74f7
2 changed files with 31 additions and 57 deletions
|
@ -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"
|
||||
);
|
||||
|
||||
|
|
|
@ -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!(),
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue