Implement key ordering for info box
This commit is contained in:
parent
e505bf2b48
commit
eb8745db09
4 changed files with 18 additions and 10 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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)| {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue