on master help sign in
Implement key ordering for info box
eb8745dDaniel Ebert
helix-term/src/keymap.rs+14−6
@@ -5,7 +5,7 @@ use helix_view::{document::Mode, info::Info, input::KeyEvent};
5use serde::Deserialize;
5use serde::Deserialize;
6use std::{
6use std::{
7 borrow::Cow,
7 borrow::Cow,
8− collections::HashMap,
8+ collections::{BTreeSet, HashMap},
9 ops::{Deref, DerefMut},
9 ops::{Deref, DerefMut},
10};
10};
11
11
@@ -137,20 +137,28 @@ impl KeyTrieNode {
137 }
137 }
138
138
139 pub fn infobox(&self) -> Info {
139 pub fn infobox(&self) -> Info {
140− let mut body: Vec<(&str, Vec<KeyEvent>)> = Vec::with_capacity(self.len());
140+ let mut body: Vec<(&str, BTreeSet<KeyEvent>)> = Vec::with_capacity(self.len());
141 for (&key, trie) in self.iter() {
141 for (&key, trie) in self.iter() {
142 let desc = match trie {
142 let desc = match trie {
143 KeyTrie::Leaf(cmd) => cmd.doc(),
143 KeyTrie::Leaf(cmd) => cmd.doc(),
144 KeyTrie::Node(n) => n.name(),
144 KeyTrie::Node(n) => n.name(),
145 };
145 };
146 match body.iter().position(|(d, _)| d == &desc) {
146 match body.iter().position(|(d, _)| d == &desc) {
147− // FIXME: multiple keys are ordered randomly (use BTreeSet)
147+ Some(pos) => {
148− Some(pos) => body[pos].1.push(key),
148+ body[pos].1.insert(key);
149+ }
150+ None => {
151+ let mut keys = BTreeSet::new();
152+ keys.insert(key);
149− None => body.push((desc, vec![key])),
153+ body.push((desc, keys));
154+ }
150 }
155 }
151 }
156 }
152 body.sort_unstable_by_key(|(_, keys)| {
157 body.sort_unstable_by_key(|(_, keys)| {
158+ self.order
159+ .iter()
153− self.order.iter().position(|&k| k == keys[0]).unwrap()
160+ .position(|&k| k == *keys.iter().next().unwrap())
161+ .unwrap()
154 });
162 });
155 let prefix = format!("{} ", self.name());
163 let prefix = format!("{} ", self.name());
156 if body.iter().all(|(desc, _)| desc.starts_with(&prefix)) {
164 if body.iter().all(|(desc, _)| desc.starts_with(&prefix)) {
helix-view/src/info.rs+2−2
@@ -1,6 +1,6 @@
1use crate::input::KeyEvent;
1use crate::input::KeyEvent;
2use helix_core::unicode::width::UnicodeWidthStr;
2use helix_core::unicode::width::UnicodeWidthStr;
3−use std::fmt::Write;
3+use std::{collections::BTreeSet, fmt::Write};
4
4
5#[derive(Debug)]
5#[derive(Debug)]
6/// Info box used in editor. Rendering logic will be in other crate.
6/// Info box used in editor. Rendering logic will be in other crate.
@@ -16,7 +16,7 @@ pub struct Info {
16}
16}
17
17
18impl Info {
18impl Info {
19− pub fn new(title: &str, body: Vec<(&str, Vec<KeyEvent>)>) -> Info {
19+ pub fn new(title: &str, body: Vec<(&str, BTreeSet<KeyEvent>)>) -> Info {
20 let body = body
20 let body = body
21 .into_iter()
21 .into_iter()
22 .map(|(desc, events)| {
22 .map(|(desc, events)| {
helix-view/src/input.rs+1−1
@@ -8,7 +8,7 @@ use crate::keyboard::{KeyCode, KeyModifiers};
8
8
9/// Represents a key event.
9/// Represents a key event.
10// We use a newtype here because we want to customize Deserialize and Display.
10// We use a newtype here because we want to customize Deserialize and Display.
11−#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy, Hash)]
11+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
12pub struct KeyEvent {
12pub struct KeyEvent {
13 pub code: KeyCode,
13 pub code: KeyCode,
14 pub modifiers: KeyModifiers,
14 pub modifiers: KeyModifiers,
helix-view/src/keyboard.rs+1−1
@@ -54,7 +54,7 @@ impl From<crossterm::event::KeyModifiers> for KeyModifiers {
54}
54}
55
55
56/// Represents a key.
56/// Represents a key.
57−#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
57+#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
58#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
58#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
59pub enum KeyCode {
59pub enum KeyCode {
60 /// Backspace key.
60 /// Backspace key.