aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/keymap.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/keymap.rs')
-rw-r--r--helix-term/src/keymap.rs68
1 files changed, 41 insertions, 27 deletions
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index b317242d..e08d7e44 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -1,4 +1,4 @@
-pub use crate::commands::Command;
+pub use crate::commands::MappableCommand;
use crate::config::Config;
use helix_core::hashmap;
use helix_view::{document::Mode, info::Info, input::KeyEvent};
@@ -92,7 +92,7 @@ macro_rules! alt {
#[macro_export]
macro_rules! keymap {
(@trie $cmd:ident) => {
- $crate::keymap::KeyTrie::Leaf($crate::commands::Command::$cmd)
+ $crate::keymap::KeyTrie::Leaf($crate::commands::MappableCommand::$cmd)
};
(@trie
@@ -120,7 +120,7 @@ macro_rules! keymap {
_key,
keymap!(@trie $value)
);
- debug_assert!(_duplicate.is_none(), "Duplicate key found: {:?}", _duplicate.unwrap());
+ assert!(_duplicate.is_none(), "Duplicate key found: {:?}", _duplicate.unwrap());
_order.push(_key);
)+
)*
@@ -222,9 +222,8 @@ impl KeyTrieNode {
.map(|(desc, keys)| (desc.strip_prefix(&prefix).unwrap(), keys))
.collect();
}
- Info::new(self.name(), body)
+ Info::from_keymap(self.name(), body)
}
-
/// Get a reference to the key trie node's order.
pub fn order(&self) -> &[KeyEvent] {
self.order.as_slice()
@@ -260,8 +259,8 @@ impl DerefMut for KeyTrieNode {
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(untagged)]
pub enum KeyTrie {
- Leaf(Command),
- Sequence(Vec<Command>),
+ Leaf(MappableCommand),
+ Sequence(Vec<MappableCommand>),
Node(KeyTrieNode),
}
@@ -304,9 +303,9 @@ impl KeyTrie {
pub enum KeymapResultKind {
/// Needs more keys to execute a command. Contains valid keys for next keystroke.
Pending(KeyTrieNode),
- Matched(Command),
+ Matched(MappableCommand),
/// Matched a sequence of commands to execute.
- MatchedSequence(Vec<Command>),
+ MatchedSequence(Vec<MappableCommand>),
/// Key was not found in the root keymap
NotFound,
/// Key is invalid in combination with previous keys. Contains keys leading upto
@@ -344,7 +343,7 @@ pub struct Keymap {
impl Keymap {
pub fn new(root: KeyTrie) -> Self {
- Keymap {
+ Self {
root,
state: Vec::new(),
sticky: None,
@@ -368,7 +367,7 @@ impl Keymap {
/// key cancels pending keystrokes. If there are no pending keystrokes but a
/// sticky node is in use, it will be cleared.
pub fn get(&mut self, key: KeyEvent) -> KeymapResult {
- if let key!(Esc) = key {
+ if key!(Esc) == key {
if !self.state.is_empty() {
return KeymapResult::new(
// Note that Esc is not included here
@@ -386,10 +385,10 @@ impl Keymap {
};
let trie = match trie_node.search(&[*first]) {
- Some(&KeyTrie::Leaf(cmd)) => {
- return KeymapResult::new(KeymapResultKind::Matched(cmd), self.sticky())
+ Some(KeyTrie::Leaf(ref cmd)) => {
+ return KeymapResult::new(KeymapResultKind::Matched(cmd.clone()), self.sticky())
}
- Some(&KeyTrie::Sequence(ref cmds)) => {
+ Some(KeyTrie::Sequence(ref cmds)) => {
return KeymapResult::new(
KeymapResultKind::MatchedSequence(cmds.clone()),
self.sticky(),
@@ -408,9 +407,9 @@ impl Keymap {
}
KeymapResult::new(KeymapResultKind::Pending(map.clone()), self.sticky())
}
- Some(&KeyTrie::Leaf(cmd)) => {
+ Some(&KeyTrie::Leaf(ref cmd)) => {
self.state.clear();
- return KeymapResult::new(KeymapResultKind::Matched(cmd), self.sticky());
+ return KeymapResult::new(KeymapResultKind::Matched(cmd.clone()), self.sticky());
}
Some(&KeyTrie::Sequence(ref cmds)) => {
self.state.clear();
@@ -477,7 +476,7 @@ impl DerefMut for Keymaps {
}
impl Default for Keymaps {
- fn default() -> Keymaps {
+ fn default() -> Self {
let normal = keymap!({ "Normal mode"
"h" | "left" => move_char_left,
"j" | "down" => move_line_down,
@@ -521,9 +520,10 @@ impl Default for Keymaps {
"r" => goto_reference,
"i" => goto_implementation,
"t" => goto_window_top,
- "m" => goto_window_middle,
+ "c" => goto_window_center,
"b" => goto_window_bottom,
"a" => goto_last_accessed_file,
+ "m" => goto_last_modified_file,
"n" => goto_next_buffer,
"p" => goto_previous_buffer,
"." => goto_last_modification,
@@ -551,6 +551,11 @@ impl Default for Keymaps {
"S" => split_selection,
";" => collapse_selection,
"A-;" => flip_selections,
+ "A-k" => expand_selection,
+ "A-j" => shrink_selection,
+ "A-h" => select_prev_sibling,
+ "A-l" => select_next_sibling,
+
"%" => select_all,
"x" => extend_line,
"X" => extend_to_line_bounds,
@@ -592,6 +597,9 @@ impl Default for Keymaps {
// paste_all
"P" => paste_before,
+ "Q" => record_macro,
+ "q" => replay_macro,
+
">" => indent,
"<" => unindent,
"=" => format_selections,
@@ -613,6 +621,8 @@ impl Default for Keymaps {
"A-(" => rotate_selection_contents_backward,
"A-)" => rotate_selection_contents_forward,
+ "A-:" => ensure_selections_forward,
+
"esc" => normal_mode,
"C-b" | "pageup" => page_up,
"C-f" | "pagedown" => page_down,
@@ -640,7 +650,7 @@ impl Default for Keymaps {
"tab" => jump_forward, // tab == <C-i>
"C-o" => jump_backward,
- // "C-s" => save_selection,
+ "C-s" => save_selection,
"space" => { "Space"
"f" => file_picker,
@@ -763,8 +773,10 @@ impl Default for Keymaps {
"del" => delete_char_forward,
"C-d" => delete_char_forward,
"ret" => insert_newline,
+ "C-j" => insert_newline,
"tab" => insert_tab,
"C-w" => delete_word_backward,
+ "A-backspace" => delete_word_backward,
"A-d" => delete_word_forward,
"left" => move_char_left,
@@ -779,6 +791,8 @@ impl Default for Keymaps {
"A-left" => move_prev_word_end,
"A-f" => move_next_word_start,
"A-right" => move_next_word_start,
+ "A-<" => goto_file_start,
+ "A->" => goto_file_end,
"pageup" => page_up,
"pagedown" => page_down,
"home" => goto_line_start,
@@ -792,7 +806,7 @@ impl Default for Keymaps {
"C-x" => completion,
"C-r" => insert_register,
});
- Keymaps(hashmap!(
+ Self(hashmap!(
Mode::Normal => Keymap::new(normal),
Mode::Select => Keymap::new(select),
Mode::Insert => Keymap::new(insert),
@@ -852,36 +866,36 @@ mod tests {
let keymap = merged_config.keys.0.get_mut(&Mode::Normal).unwrap();
assert_eq!(
keymap.get(key!('i')).kind,
- KeymapResultKind::Matched(Command::normal_mode),
+ KeymapResultKind::Matched(MappableCommand::normal_mode),
"Leaf should replace leaf"
);
assert_eq!(
keymap.get(key!('无')).kind,
- KeymapResultKind::Matched(Command::insert_mode),
+ KeymapResultKind::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(key!('z')).kind,
- KeymapResultKind::Matched(Command::jump_backward),
+ KeymapResultKind::Matched(MappableCommand::jump_backward),
"Leaf should replace node"
);
// Assumes that `g` is a node in default keymap
assert_eq!(
keymap.root().search(&[key!('g'), key!('$')]).unwrap(),
- &KeyTrie::Leaf(Command::goto_line_end),
+ &KeyTrie::Leaf(MappableCommand::goto_line_end),
"Leaf should be present in merged subnode"
);
// Assumes that `gg` is in default keymap
assert_eq!(
keymap.root().search(&[key!('g'), key!('g')]).unwrap(),
- &KeyTrie::Leaf(Command::delete_char_forward),
+ &KeyTrie::Leaf(MappableCommand::delete_char_forward),
"Leaf should replace old leaf in merged subnode"
);
// Assumes that `ge` is in default keymap
assert_eq!(
keymap.root().search(&[key!('g'), key!('e')]).unwrap(),
- &KeyTrie::Leaf(Command::goto_last_line),
+ &KeyTrie::Leaf(MappableCommand::goto_last_line),
"Old leaves in subnode should be present in merged node"
);
@@ -915,7 +929,7 @@ mod tests {
.root()
.search(&[key!(' '), key!('s'), key!('v')])
.unwrap(),
- &KeyTrie::Leaf(Command::vsplit),
+ &KeyTrie::Leaf(MappableCommand::vsplit),
"Leaf should be present in merged subnode"
);
// Make sure an order was set during merge