on master help sign in
keymap: Store pending/sticky on the root level
commit7909d6f05e4d651d904886aa53ec4bd250294e73 authorBlaž Hrastnik <blaz@mxxn.io> dateSun 20 Mar 2022, 15:50 (5 years ago) parentcfd992b
4 files changed+77−90
helix-term/src/commands.rs+1−1 helix-term/src/config.rs+1−1 helix-term/src/keymap.rs+68−80 helix-term/src/ui/editor.rs+7−8
helix-term/src/commands.rs+1−1
@@ -2105,7 +2105,7 @@ pub fn command_palette(cx: &mut Context) {
21052105 move |compositor: &mut Compositor, cx: &mut compositor::Context| {
21062106 let doc = doc_mut!(cx.editor);
21072107 let keymap =
2108− compositor.find::<ui::EditorView>().unwrap().keymaps[&doc.mode].reverse_map();
2108+ compositor.find::<ui::EditorView>().unwrap().keymaps.map[&doc.mode].reverse_map();
21092109
21102110 let mut commands: Vec<MappableCommand> = MappableCommand::STATIC_COMMAND_LIST.into();
21112111 commands.extend(typed::TYPABLE_COMMAND_LIST.iter().map(|cmd| {
helix-term/src/config.rs+1−1
@@ -43,7 +43,7 @@ mod tests {
4343 assert_eq!(
4444 toml::from_str::<Config>(sample_keymaps).unwrap(),
4545 Config {
46− keys: Keymaps(hashmap! {
46+ keys: Keymaps::new(hashmap! {
4747 Mode::Insert => Keymap::new(keymap!({ "Insert mode"
4848 "y" => move_line_down,
4949 "S-C-a" => delete_selection,
helix-term/src/keymap.rs+68−80
@@ -328,26 +328,15 @@ impl<'a> KeymapResult<'a> {
328328}
329329
330330#[derive(Debug, Clone, PartialEq, Deserialize)]
331+#[serde(transparent)]
331332pub struct Keymap {
332333 /// Always a Node
333− #[serde(flatten)]
334334 root: KeyTrie,
335− /// Stores pending keys waiting for the next key. This is relative to a
336− /// sticky node if one is in use.
337− #[serde(skip)]
338− state: Vec<KeyEvent>,
339− /// Stores the sticky node if one is activated.
340− #[serde(skip)]
341− sticky: Option<KeyTrieNode>,
342335}
343336
344337impl Keymap {
345338 pub fn new(root: KeyTrie) -> Self {
346− Keymap {
347− root,
348− state: Vec::new(),
349− sticky: None,
350− }
339+ Keymap { root }
351340 }
352341
353342 pub fn reverse_map(&self) -> HashMap<String, Vec<Vec<KeyEvent>>> {
@@ -387,19 +376,65 @@ impl Keymap {
387376 &self.root
388377 }
389378
390− pub fn sticky(&self) -> Option<&KeyTrieNode> {
391− self.sticky.as_ref()
379+ pub fn merge(&mut self, other: Self) {
380+ self.root.merge_nodes(other.root);
381+ }
382+}
383+
384+impl Deref for Keymap {
385+ type Target = KeyTrieNode;
386+
387+ fn deref(&self) -> &Self::Target {
388+ self.root.node().unwrap()
392389 }
390+}
393391
394− /// Returns list of keys waiting to be disambiguated.
392+impl Default for Keymap {
393+ fn default() -> Self {
394+ Self::new(KeyTrie::Node(KeyTrieNode::default()))
395+ }
396+}
397+
398+#[derive(Debug, Clone, PartialEq, Deserialize)]
399+pub struct Keymaps {
400+ #[serde(flatten)]
401+ pub map: HashMap<Mode, Keymap>,
402+
403+ /// Stores pending keys waiting for the next key. This is relative to a
404+ /// sticky node if one is in use.
405+ #[serde(skip)]
406+ state: Vec<KeyEvent>,
407+
408+ /// Stores the sticky node if one is activated.
409+ #[serde(skip)]
410+ pub sticky: Option<KeyTrieNode>,
411+}
412+
413+impl Keymaps {
414+ pub fn new(map: HashMap<Mode, Keymap>) -> Self {
415+ Self {
416+ map,
417+ state: Vec::new(),
418+ sticky: None,
419+ }
420+ }
421+
422+ /// Returns list of keys waiting to be disambiguated in current mode.
395423 pub fn pending(&self) -> &[KeyEvent] {
396424 &self.state
397425 }
398426
427+ pub fn sticky(&self) -> Option<&KeyTrieNode> {
428+ self.sticky.as_ref()
429+ }
430+
399431 /// Lookup `key` in the keymap to try and find a command to execute. Escape
400432 /// key cancels pending keystrokes. If there are no pending keystrokes but a
401433 /// sticky node is in use, it will be cleared.
402− pub fn get(&mut self, key: KeyEvent) -> KeymapResult {
434+ pub fn get(&mut self, mode: Mode, key: KeyEvent) -> KeymapResult {
435+ // TODO: remove the sticky part and look up manually
436+ let keymap = &self.map[&mode];
437+
403438 if key!(Esc) == key {
404439 if !self.state.is_empty() {
405440 return KeymapResult::new(
@@ -414,7 +449,7 @@ impl Keymap {
414449 let first = self.state.get(0).unwrap_or(&key);
415450 let trie_node = match self.sticky {
416451 Some(ref trie) => Cow::Owned(KeyTrie::Node(trie.clone())),
417− None => Cow::Borrowed(&self.root),
452+ None => Cow::Borrowed(&keymap.root),
418453 };
419454
420455 let trie = match trie_node.search(&[*first]) {
@@ -457,55 +492,6 @@ impl Keymap {
457492 ),
458493 }
459494 }
460−
461− pub fn merge(&mut self, other: Self) {
462− self.root.merge_nodes(other.root);
463− }
464−}
465−
466−impl Deref for Keymap {
467− type Target = KeyTrieNode;
468−
469− fn deref(&self) -> &Self::Target {
470− self.root.node().unwrap()
471− }
472−}
473−
474−impl Default for Keymap {
475− fn default() -> Self {
476− Self::new(KeyTrie::Node(KeyTrieNode::default()))
477− }
478−}
479−
480−#[derive(Debug, Clone, PartialEq, Deserialize)]
481−#[serde(transparent)]
482−pub struct Keymaps(pub HashMap<Mode, Keymap>);
483−
484−impl Keymaps {
485− /// Returns list of keys waiting to be disambiguated in current mode.
486− pub fn pending(&self) -> &[KeyEvent] {
487− self.0
488− .values()
489− .find_map(|keymap| match keymap.pending().is_empty() {
490− true => None,
491− false => Some(keymap.pending()),
492− })
493− .unwrap_or_default()
494− }
495−}
496−
497−impl Deref for Keymaps {
498− type Target = HashMap<Mode, Keymap>;
499−
500− fn deref(&self) -> &Self::Target {
501− &self.0
502− }
503−}
504−
505−impl DerefMut for Keymaps {
506− fn deref_mut(&mut self) -> &mut Self::Target {
507− &mut self.0
508− }
509495}
510496
511497impl Default for Keymaps {
@@ -856,7 +842,7 @@ impl Default for Keymaps {
856842 "C-x" => completion,
857843 "C-r" => insert_register,
858844 });
859− Self(hashmap!(
845+ Self::new(hashmap!(
860846 Mode::Normal => Keymap::new(normal),
861847 Mode::Select => Keymap::new(select),
862848 Mode::Insert => Keymap::new(insert),
@@ -867,8 +853,8 @@ impl Default for Keymaps {
867853/// Merge default config keys with user overwritten keys for custom user config.
868854pub fn merge_keys(mut config: Config) -> Config {
869855 let mut delta = std::mem::take(&mut config.keys);
870− for (mode, keys) in &mut *config.keys {
871− keys.merge(delta.remove(mode).unwrap_or_default())
856+ for (mode, keys) in &mut config.keys.map {
857+ keys.merge(delta.map.remove(mode).unwrap_or_default())
872858 }
873859 config
874860}
@@ -895,7 +881,7 @@ mod tests {
895881 #[test]
896882 fn merge_partial_keys() {
897883 let config = Config {
898− keys: Keymaps(hashmap! {
884+ keys: Keymaps::new(hashmap! {
899885 Mode::Normal => Keymap::new(
900886 keymap!({ "Normal mode"
901887 "i" => normal_mode,
@@ -913,23 +899,25 @@ mod tests {
913899 let mut merged_config = merge_keys(config.clone());
914900 assert_ne!(config, merged_config);
915901
916− let keymap = merged_config.keys.0.get_mut(&Mode::Normal).unwrap();
902+ let keymap = &mut merged_config.keys;
917903 assert_eq!(
918− keymap.get(key!('i')).kind,
904+ keymap.get(Mode::Normal, key!('i')).kind,
919905 KeymapResultKind::Matched(MappableCommand::normal_mode),
920906 "Leaf should replace leaf"
921907 );
922908 assert_eq!(
923− keymap.get(key!('无')).kind,
909+ keymap.get(Mode::Normal, key!('无')).kind,
924910 KeymapResultKind::Matched(MappableCommand::insert_mode),
925911 "New leaf should be present in merged keymap"
926912 );
927913 // Assumes that z is a node in the default keymap
928914 assert_eq!(
929− keymap.get(key!('z')).kind,
915+ keymap.get(Mode::Normal, key!('z')).kind,
930916 KeymapResultKind::Matched(MappableCommand::jump_backward),
931917 "Leaf should replace node"
932918 );
919+
920+ let keymap = merged_config.keys.map.get_mut(&Mode::Normal).unwrap();
933921 // Assumes that `g` is a node in default keymap
934922 assert_eq!(
935923 keymap.root().search(&[key!('g'), key!('$')]).unwrap(),
@@ -949,14 +937,14 @@ mod tests {
949937 "Old leaves in subnode should be present in merged node"
950938 );
951939
952− assert!(merged_config.keys.0.get(&Mode::Normal).unwrap().len() > 1);
953− assert!(merged_config.keys.0.get(&Mode::Insert).unwrap().len() > 0);
940+ assert!(merged_config.keys.map.get(&Mode::Normal).unwrap().len() > 1);
941+ assert!(merged_config.keys.map.get(&Mode::Insert).unwrap().len() > 0);
954942 }
955943
956944 #[test]
957945 fn order_should_be_set() {
958946 let config = Config {
959− keys: Keymaps(hashmap! {
947+ keys: Keymaps::new(hashmap! {
960948 Mode::Normal => Keymap::new(
961949 keymap!({ "Normal mode"
962950 "space" => { ""
@@ -972,7 +960,7 @@ mod tests {
972960 };
973961 let mut merged_config = merge_keys(config.clone());
974962 assert_ne!(config, merged_config);
975− let keymap = merged_config.keys.0.get_mut(&Mode::Normal).unwrap();
963+ let keymap = merged_config.keys.map.get_mut(&Mode::Normal).unwrap();
976964 // Make sure mapping works
977965 assert_eq!(
978966 keymap
@@ -990,7 +978,7 @@ mod tests {
990978 #[test]
991979 fn aliased_modes_are_same_in_default_keymap() {
992980 let keymaps = Keymaps::default();
993− let root = keymaps.get(&Mode::Normal).unwrap().root();
981+ let root = keymaps.map.get(&Mode::Normal).unwrap().root();
994982 assert_eq!(
995983 root.search(&[key!(' '), key!('w')]).unwrap(),
996984 root.search(&["C-w".parse::<KeyEvent>().unwrap()]).unwrap(),
helix-term/src/ui/editor.rs+7−8
@@ -703,7 +703,7 @@ impl EditorView {
703703 event: KeyEvent,
704704 ) -> Option<KeymapResult> {
705705 cxt.editor.autoinfo = None;
706− let key_result = self.keymaps.get_mut(&mode).unwrap().get(event);
706+ let key_result = self.keymaps.get(mode, event);
707707 cxt.editor.autoinfo = key_result.sticky.map(|node| node.infobox());
708708
709709 match &key_result.kind {
@@ -733,7 +733,7 @@ impl EditorView {
733733 Some(ch) => commands::insert::insert_char(cx, ch),
734734 None => {
735735 if let KeymapResultKind::Matched(command) =
736− self.keymaps.get_mut(&Mode::Insert).unwrap().get(ev).kind
736+ self.keymaps.get(Mode::Insert, ev).kind
737737 {
738738 command.execute(cx);
739739 }
@@ -1182,12 +1182,11 @@ impl Component for EditorView {
11821182 // how we entered insert mode is important, and we should track that so
11831183 // we can repeat the side effect.
11841184
1185− self.last_insert.0 =
1186− match self.keymaps.get_mut(&mode).unwrap().get(key).kind {
1187− KeymapResultKind::Matched(command) => command,
1188− // FIXME: insert mode can only be entered through single KeyCodes
1189− _ => unimplemented!(),
1190− };
1185+ self.last_insert.0 = match self.keymaps.get(mode, key).kind {
1186+ KeymapResultKind::Matched(command) => command,
1187+ // FIXME: insert mode can only be entered through single KeyCodes
1188+ _ => unimplemented!(),
1189+ };
11911190 self.last_insert.1.clear();
11921191 }
11931192 (Mode::Insert, Mode::Normal) => {