Skip to content

Commit

Permalink
No need for KeymapResult anymore since we can query .sticky()
Browse files Browse the repository at this point in the history
  • Loading branch information
archseer committed Mar 20, 2022
1 parent e4b88d1 commit 15d963b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 56 deletions.
59 changes: 18 additions & 41 deletions helix-term/src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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 {
Expand Down Expand Up @@ -437,11 +423,9 @@ impl Keymaps {

if key!(Esc) == key {
if !self.state.is_empty() {
return KeymapResult::new(
return
// Note that Esc is not included here
KeymapResultKind::Cancelled(self.state.drain(..).collect()),
self.sticky(),
);
KeymapResult::Cancelled(self.state.drain(..).collect());
}
self.sticky = None;
}
Expand All @@ -454,15 +438,13 @@ 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,
};

Expand All @@ -473,23 +455,18 @@ 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()),
}
}
}
Expand Down Expand Up @@ -901,19 +878,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"
);

Expand Down
30 changes: 15 additions & 15 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
commands,
compositor::{Component, Context, EventResult},
key,
keymap::{KeymapResult, KeymapResultKind, Keymaps},
keymap::{KeymapResult, Keymaps},
ui::{Completion, ProgressSpinners},
};

Expand Down Expand Up @@ -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,
Expand All @@ -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);
}
Expand Down Expand Up @@ -1183,8 +1183,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!(),
};
Expand Down

0 comments on commit 15d963b

Please sign in to comment.