Implement key ordering for info box

imgbot
Daniel Ebert 3 years ago committed by Blaž Hrastnik
parent e505bf2b48
commit eb8745db09

@ -5,7 +5,7 @@ use helix_view::{document::Mode, info::Info, input::KeyEvent};
use serde::Deserialize; use serde::Deserialize;
use std::{ use std::{
borrow::Cow, borrow::Cow,
collections::HashMap, collections::{BTreeSet, HashMap},
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
}; };
@ -137,20 +137,28 @@ impl KeyTrieNode {
} }
pub fn infobox(&self) -> Info { 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() { for (&key, trie) in self.iter() {
let desc = match trie { let desc = match trie {
KeyTrie::Leaf(cmd) => cmd.doc(), KeyTrie::Leaf(cmd) => cmd.doc(),
KeyTrie::Node(n) => n.name(), KeyTrie::Node(n) => n.name(),
}; };
match body.iter().position(|(d, _)| d == &desc) { match body.iter().position(|(d, _)| d == &desc) {
// FIXME: multiple keys are ordered randomly (use BTreeSet) Some(pos) => {
Some(pos) => body[pos].1.push(key), body[pos].1.insert(key);
None => body.push((desc, vec![key])), }
None => {
let mut keys = BTreeSet::new();
keys.insert(key);
body.push((desc, keys));
}
} }
} }
body.sort_unstable_by_key(|(_, 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()); let prefix = format!("{} ", self.name());
if body.iter().all(|(desc, _)| desc.starts_with(&prefix)) { if body.iter().all(|(desc, _)| desc.starts_with(&prefix)) {

@ -1,6 +1,6 @@
use crate::input::KeyEvent; use crate::input::KeyEvent;
use helix_core::unicode::width::UnicodeWidthStr; use helix_core::unicode::width::UnicodeWidthStr;
use std::fmt::Write; use std::{collections::BTreeSet, fmt::Write};
#[derive(Debug)] #[derive(Debug)]
/// Info box used in editor. Rendering logic will be in other crate. /// Info box used in editor. Rendering logic will be in other crate.
@ -16,7 +16,7 @@ pub struct Info {
} }
impl 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 let body = body
.into_iter() .into_iter()
.map(|(desc, events)| { .map(|(desc, events)| {

@ -8,7 +8,7 @@ use crate::keyboard::{KeyCode, KeyModifiers};
/// Represents a key event. /// Represents a key event.
// We use a newtype here because we want to customize Deserialize and Display. // 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 struct KeyEvent {
pub code: KeyCode, pub code: KeyCode,
pub modifiers: KeyModifiers, pub modifiers: KeyModifiers,

@ -54,7 +54,7 @@ impl From<crossterm::event::KeyModifiers> for KeyModifiers {
} }
/// Represents a key. /// 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))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum KeyCode { pub enum KeyCode {
/// Backspace key. /// Backspace key.

Loading…
Cancel
Save