diff options
author | Daniel Ebert | 2021-11-01 14:50:12 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2021-11-03 02:56:55 +0000 |
commit | eb8745db0999a50464ac183baa138c4e511430f2 (patch) | |
tree | 6089d754bf8d27f7cb865422d04947b4fa785026 | |
parent | e505bf2b4809681840d1684a23ad21255fca290d (diff) |
Implement key ordering for info box
-rw-r--r-- | helix-term/src/keymap.rs | 20 | ||||
-rw-r--r-- | helix-view/src/info.rs | 4 | ||||
-rw-r--r-- | helix-view/src/input.rs | 2 | ||||
-rw-r--r-- | helix-view/src/keyboard.rs | 2 |
4 files changed, 18 insertions, 10 deletions
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index cd953c5c..827f71d9 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -5,7 +5,7 @@ use helix_view::{document::Mode, info::Info, input::KeyEvent}; use serde::Deserialize; use std::{ borrow::Cow, - collections::HashMap, + collections::{BTreeSet, HashMap}, ops::{Deref, DerefMut}, }; @@ -137,20 +137,28 @@ impl KeyTrieNode { } pub fn infobox(&self) -> Info { - let mut body: Vec<(&str, Vec<KeyEvent>)> = Vec::with_capacity(self.len()); + let mut body: Vec<(&str, BTreeSet<KeyEvent>)> = Vec::with_capacity(self.len()); for (&key, trie) in self.iter() { let desc = match trie { KeyTrie::Leaf(cmd) => cmd.doc(), KeyTrie::Node(n) => n.name(), }; match body.iter().position(|(d, _)| d == &desc) { - // FIXME: multiple keys are ordered randomly (use BTreeSet) - Some(pos) => body[pos].1.push(key), - None => body.push((desc, vec![key])), + Some(pos) => { + body[pos].1.insert(key); + } + None => { + let mut keys = BTreeSet::new(); + keys.insert(key); + body.push((desc, keys)); + } } } body.sort_unstable_by_key(|(_, keys)| { - self.order.iter().position(|&k| k == keys[0]).unwrap() + self.order + .iter() + .position(|&k| k == *keys.iter().next().unwrap()) + .unwrap() }); let prefix = format!("{} ", self.name()); if body.iter().all(|(desc, _)| desc.starts_with(&prefix)) { diff --git a/helix-view/src/info.rs b/helix-view/src/info.rs index 629a3112..b5a002fa 100644 --- a/helix-view/src/info.rs +++ b/helix-view/src/info.rs @@ -1,6 +1,6 @@ use crate::input::KeyEvent; use helix_core::unicode::width::UnicodeWidthStr; -use std::fmt::Write; +use std::{collections::BTreeSet, fmt::Write}; #[derive(Debug)] /// Info box used in editor. Rendering logic will be in other crate. @@ -16,7 +16,7 @@ pub struct Info { } impl Info { - pub fn new(title: &str, body: Vec<(&str, Vec<KeyEvent>)>) -> Info { + pub fn new(title: &str, body: Vec<(&str, BTreeSet<KeyEvent>)>) -> Info { let body = body .into_iter() .map(|(desc, events)| { diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 1e0ddfe2..580204cc 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -8,7 +8,7 @@ use crate::keyboard::{KeyCode, KeyModifiers}; /// Represents a key event. // We use a newtype here because we want to customize Deserialize and Display. -#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy, Hash)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)] pub struct KeyEvent { pub code: KeyCode, pub modifiers: KeyModifiers, diff --git a/helix-view/src/keyboard.rs b/helix-view/src/keyboard.rs index 26a4d6d2..810aa063 100644 --- a/helix-view/src/keyboard.rs +++ b/helix-view/src/keyboard.rs @@ -54,7 +54,7 @@ impl From<crossterm::event::KeyModifiers> for KeyModifiers { }
/// Represents a key.
-#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
+#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum KeyCode {
/// Backspace key.
|