Repository: helix-editor/helix
File: helix-term/src/keymap.rs (Rust)

Code before:

    pub fn root(&self) -> &KeyTrie {
        &self.root
    }

    /// Returns list of keys waiting to be disambiguated.
    pub fn pending(&self) -> &[KeyEvent] {
        &self.state
    }

    /// Lookup `key` in the keymap to try and find a command to execute
    pub fn get(&mut self, key: KeyEvent) -> KeymapResult {
        let &first = self.state.get(0).unwrap_or(&key);
        let trie = match self.root.search(&[first]) {
            Some(&KeyTrie::Leaf(cmd)) => return KeymapResult::Matched(cmd),
            None => return KeymapResult::NotFound,
            Some(t) => t,
        };
        self.state.push(key);
        match trie.search(&self.state[1..]) {
            Some(&KeyTrie::Node(ref map)) => KeymapResult::Pending(map.clone()),
            Some(&KeyTrie::Leaf(command)) => {
                self.state.clear();
                KeymapResult::Matched(command)
            }
            Some(&KeyTrie::Sequence(ref commands)) => {
                self.state.clear();
                KeymapResult::MatchedSequence(commands)
            }
            None => KeymapResult::Cancelled(self.state.drain(..).collect()),
        }
    }

    pub fn merge(&mut self, other: Self) {
        self.root.merge_nodes(other.root);
    }
}

impl Deref for Keymap {
    type Target = KeyTrieNode;

    fn deref(&self) -> &Self::Target {
        self.root.node().unwrap()
    }
}

impl Default for Keymap {
    fn default() -> Self {
        Self::new(KeyTrie::Node(KeyTrieNode::default()))
    }
}

Review comment (suggestion):
`Sequence` will also need to be handled at the beginning of this function:

```rust
        let trie = match self.root.search(&[first]) {
            Some(&KeyTrie::Leaf(cmd)) => return KeymapResult::Matched(cmd),
	        Some(&KeyTrie::Sequence(seq)) => return KeymapResult::MatchedSequence(seq),		
            None => return KeymapResult::NotFound,
            Some(t) => t,
        };
```

Code after:
    Matched(Command),
    /// Matched a sequence of commands to execute.
    MatchedSequence(Vec<Command>),
    /// Key was not found in the root keymap
    NotFound,
    /// Key is invalid in combination with previous keys. Contains keys leading upto
    /// and including current (invalid) key.
    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)]
pub struct Keymap {
    /// Always a Node
    #[serde(flatten)]
    root: KeyTrie,
    /// Stores pending keys waiting for the next key. This is relative to a
    /// sticky node if one is in use.
    #[serde(skip)]
    state: Vec<KeyEvent>,
    /// Stores the sticky node if one is activated.
    #[serde(skip)]
    sticky: Option<KeyTrieNode>,
}

impl Keymap {
    pub fn new(root: KeyTrie) -> Self {
        Keymap {
            root,
            state: Vec::new(),
            sticky: None,
        }
    }

    pub fn root(&self) -> &KeyTrie {
        &self.root
    }