themes/shortcuts: preserve order of keys
parent
8a6bf3b217
commit
bb4754e38a
|
@ -46,15 +46,13 @@ pub mod svg;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use indexmap::IndexMap;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::{Key, StatusEvent, UIEvent};
|
|
||||||
|
|
||||||
pub type ComponentId = Uuid;
|
pub type ComponentId = Uuid;
|
||||||
|
|
||||||
pub type ShortcutMap = HashMap<&'static str, Key>;
|
pub type ShortcutMap = IndexMap<&'static str, Key>;
|
||||||
pub type ShortcutMaps = HashMap<&'static str, ShortcutMap>;
|
pub type ShortcutMaps = IndexMap<&'static str, ShortcutMap>;
|
||||||
|
|
||||||
/// Types implementing this Trait can draw on the terminal and receive events.
|
/// Types implementing this Trait can draw on the terminal and receive events.
|
||||||
/// If a type wants to skip drawing if it has not changed anything, it can hold some flag in its
|
/// If a type wants to skip drawing if it has not changed anything, it can hold some flag in its
|
||||||
|
|
|
@ -610,7 +610,7 @@ impl Component for Pager {
|
||||||
self.dirty = value;
|
self.dirty = value;
|
||||||
}
|
}
|
||||||
fn get_shortcuts(&self, context: &Context) -> ShortcutMaps {
|
fn get_shortcuts(&self, context: &Context) -> ShortcutMaps {
|
||||||
let config_map: HashMap<&'static str, Key> = context.settings.shortcuts.pager.key_values();
|
let config_map: IndexMap<&'static str, Key> = context.settings.shortcuts.pager.key_values();
|
||||||
let mut ret: ShortcutMaps = Default::default();
|
let mut ret: ShortcutMaps = Default::default();
|
||||||
ret.insert(Pager::DESCRIPTION, config_map);
|
ret.insert(Pager::DESCRIPTION, config_map);
|
||||||
ret
|
ret
|
||||||
|
@ -1438,9 +1438,7 @@ impl Component for Tabbed {
|
||||||
let mut max_width =
|
let mut max_width =
|
||||||
"Press ? to close, use COMMAND \"search\" to find shortcuts".len() + 3;
|
"Press ? to close, use COMMAND \"search\" to find shortcuts".len() + 3;
|
||||||
|
|
||||||
let mut shortcuts = children_maps.iter().collect::<Vec<_>>();
|
for (desc, shortcuts) in children_maps.iter() {
|
||||||
shortcuts.sort_by_key(|(k, _)| *k);
|
|
||||||
for (desc, shortcuts) in shortcuts.iter() {
|
|
||||||
max_length += shortcuts.len() + 3;
|
max_length += shortcuts.len() + 3;
|
||||||
max_width = std::cmp::max(
|
max_width = std::cmp::max(
|
||||||
max_width,
|
max_width,
|
||||||
|
@ -1508,7 +1506,7 @@ impl Component for Tabbed {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let mut idx = 2;
|
let mut idx = 2;
|
||||||
for (desc, shortcuts) in shortcuts.iter() {
|
for (desc, shortcuts) in children_maps.iter() {
|
||||||
write_string_to_grid(
|
write_string_to_grid(
|
||||||
desc,
|
desc,
|
||||||
&mut self.help_content,
|
&mut self.help_content,
|
||||||
|
@ -1519,8 +1517,6 @@ impl Component for Tabbed {
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
idx += 2;
|
idx += 2;
|
||||||
let mut shortcuts = shortcuts.iter().collect::<Vec<_>>();
|
|
||||||
shortcuts.sort_unstable_by_key(|(ref k, _)| *k);
|
|
||||||
for (k, v) in shortcuts {
|
for (k, v) in shortcuts {
|
||||||
debug!(&(k, v));
|
debug!(&(k, v));
|
||||||
let (x, y) = write_string_to_grid(
|
let (x, y) = write_string_to_grid(
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
use super::DotAddressable;
|
use super::DotAddressable;
|
||||||
use crate::terminal::Key;
|
use crate::terminal::Key;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use melib::{MeliError, Result};
|
use melib::{MeliError, Result};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! shortcut {
|
macro_rules! shortcut {
|
||||||
|
@ -121,7 +121,7 @@ macro_rules! shortcut_key_values {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Returns a hashmap of all shortcuts and their values
|
/// Returns a hashmap of all shortcuts and their values
|
||||||
pub fn key_values(&self) -> HashMap<&'static str, Key> {
|
pub fn key_values(&self) -> IndexMap<&'static str, Key> {
|
||||||
[
|
[
|
||||||
$((stringify!($fname),(self.$fname).clone()),)*
|
$((stringify!($fname),(self.$fname).clone()),)*
|
||||||
].iter().cloned().collect()
|
].iter().cloned().collect()
|
||||||
|
|
|
@ -30,11 +30,12 @@
|
||||||
|
|
||||||
use crate::terminal::{Attr, Color};
|
use crate::terminal::{Attr, Color};
|
||||||
use crate::Context;
|
use crate::Context;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use melib::{MeliError, Result};
|
use melib::{MeliError, Result};
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn value(context: &Context, key: &'static str) -> ThemeAttribute {
|
pub fn value(context: &Context, key: &'static str) -> ThemeAttribute {
|
||||||
|
@ -486,16 +487,16 @@ impl<'de> Deserialize<'de> for ThemeValue<Color> {
|
||||||
pub struct Themes {
|
pub struct Themes {
|
||||||
pub light: Theme,
|
pub light: Theme,
|
||||||
pub dark: Theme,
|
pub dark: Theme,
|
||||||
pub other_themes: HashMap<String, Theme>,
|
pub other_themes: IndexMap<String, Theme>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
color_aliases: HashMap<Cow<'static, str>, ThemeValue<Color>>,
|
color_aliases: IndexMap<Cow<'static, str>, ThemeValue<Color>>,
|
||||||
attr_aliases: HashMap<Cow<'static, str>, ThemeValue<Attr>>,
|
attr_aliases: IndexMap<Cow<'static, str>, ThemeValue<Attr>>,
|
||||||
#[cfg(feature = "regexp")]
|
#[cfg(feature = "regexp")]
|
||||||
text_format_regexps: HashMap<Cow<'static, str>, SmallVec<[TextFormatterSetting; 32]>>,
|
text_format_regexps: IndexMap<Cow<'static, str>, SmallVec<[TextFormatterSetting; 32]>>,
|
||||||
pub keys: HashMap<Cow<'static, str>, ThemeAttributeInner>,
|
pub keys: IndexMap<Cow<'static, str>, ThemeAttributeInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "regexp")]
|
#[cfg(feature = "regexp")]
|
||||||
|
@ -734,14 +735,14 @@ mod regexp {
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
impl Deref for Theme {
|
impl Deref for Theme {
|
||||||
type Target = HashMap<Cow<'static, str>, ThemeAttributeInner>;
|
type Target = IndexMap<Cow<'static, str>, ThemeAttributeInner>;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.keys
|
&self.keys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for Theme {
|
impl DerefMut for Theme {
|
||||||
fn deref_mut(&mut self) -> &mut HashMap<Cow<'static, str>, ThemeAttributeInner> {
|
fn deref_mut(&mut self) -> &mut IndexMap<Cow<'static, str>, ThemeAttributeInner> {
|
||||||
&mut self.keys
|
&mut self.keys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -766,19 +767,19 @@ impl<'de> Deserialize<'de> for Themes {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
dark: ThemeOptions,
|
dark: ThemeOptions,
|
||||||
#[serde(flatten, default)]
|
#[serde(flatten, default)]
|
||||||
other_themes: HashMap<String, ThemeOptions>,
|
other_themes: IndexMap<String, ThemeOptions>,
|
||||||
}
|
}
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default)]
|
||||||
struct ThemeOptions {
|
struct ThemeOptions {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
color_aliases: HashMap<Cow<'static, str>, ThemeValue<Color>>,
|
color_aliases: IndexMap<Cow<'static, str>, ThemeValue<Color>>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
attr_aliases: HashMap<Cow<'static, str>, ThemeValue<Attr>>,
|
attr_aliases: IndexMap<Cow<'static, str>, ThemeValue<Attr>>,
|
||||||
#[cfg(feature = "regexp")]
|
#[cfg(feature = "regexp")]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
text_format_regexps: HashMap<Cow<'static, str>, HashMap<String, RegexpOptions>>,
|
text_format_regexps: IndexMap<Cow<'static, str>, IndexMap<String, RegexpOptions>>,
|
||||||
#[serde(flatten, default)]
|
#[serde(flatten, default)]
|
||||||
keys: HashMap<Cow<'static, str>, ThemeAttributeInnerOptions>,
|
keys: IndexMap<Cow<'static, str>, ThemeAttributeInnerOptions>,
|
||||||
}
|
}
|
||||||
#[cfg(feature = "regexp")]
|
#[cfg(feature = "regexp")]
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default)]
|
||||||
|
@ -1284,9 +1285,9 @@ impl Themes {
|
||||||
|
|
||||||
impl Default for Themes {
|
impl Default for Themes {
|
||||||
fn default() -> Themes {
|
fn default() -> Themes {
|
||||||
let mut light = HashMap::default();
|
let mut light = IndexMap::default();
|
||||||
let mut dark = HashMap::default();
|
let mut dark = IndexMap::default();
|
||||||
let other_themes = HashMap::default();
|
let other_themes = IndexMap::default();
|
||||||
|
|
||||||
macro_rules! add {
|
macro_rules! add {
|
||||||
($key:literal, $($theme:ident={ $($name:ident : $val:expr),*$(,)? }),*$(,)?) => {
|
($key:literal, $($theme:ident={ $($name:ident : $val:expr),*$(,)? }),*$(,)?) => {
|
||||||
|
@ -1684,9 +1685,9 @@ impl Serialize for Themes {
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let mut dark: HashMap<Cow<'static, str>, ThemeAttribute> = Default::default();
|
let mut dark: IndexMap<Cow<'static, str>, ThemeAttribute> = Default::default();
|
||||||
let mut light: HashMap<Cow<'static, str>, ThemeAttribute> = Default::default();
|
let mut light: IndexMap<Cow<'static, str>, ThemeAttribute> = Default::default();
|
||||||
let mut other_themes: HashMap<String, _> = Default::default();
|
let mut other_themes: IndexMap<String, _> = Default::default();
|
||||||
|
|
||||||
for k in self.dark.keys() {
|
for k in self.dark.keys() {
|
||||||
dark.insert(
|
dark.insert(
|
||||||
|
@ -1711,7 +1712,7 @@ impl Serialize for Themes {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, t) in self.other_themes.iter() {
|
for (name, t) in self.other_themes.iter() {
|
||||||
let mut new_map: HashMap<Cow<'static, str>, ThemeAttribute> = Default::default();
|
let mut new_map: IndexMap<Cow<'static, str>, ThemeAttribute> = Default::default();
|
||||||
|
|
||||||
for k in t.keys() {
|
for k in t.keys() {
|
||||||
new_map.insert(
|
new_map.insert(
|
||||||
|
@ -1746,8 +1747,8 @@ fn is_cyclic(theme: &Theme) -> std::result::Result<(), String> {
|
||||||
fn is_cyclic_util<'a>(
|
fn is_cyclic_util<'a>(
|
||||||
course: Course,
|
course: Course,
|
||||||
k: &'a Cow<'static, str>,
|
k: &'a Cow<'static, str>,
|
||||||
visited: &mut HashMap<(&'a Cow<'static, str>, Course), bool>,
|
visited: &mut IndexMap<(&'a Cow<'static, str>, Course), bool>,
|
||||||
stack: &mut HashMap<(&'a Cow<'static, str>, Course), bool>,
|
stack: &mut IndexMap<(&'a Cow<'static, str>, Course), bool>,
|
||||||
path: &mut SmallVec<[(&'a Cow<'static, str>, Course); 16]>,
|
path: &mut SmallVec<[(&'a Cow<'static, str>, Course); 16]>,
|
||||||
theme: &'a Theme,
|
theme: &'a Theme,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -1954,7 +1955,7 @@ fn is_cyclic(theme: &Theme) -> std::result::Result<(), String> {
|
||||||
.keys()
|
.keys()
|
||||||
.map(|k| ((k, Course::AttrAlias), false)),
|
.map(|k| ((k, Course::AttrAlias), false)),
|
||||||
)
|
)
|
||||||
.collect::<HashMap<(&Cow<'static, str>, Course), bool>>();
|
.collect::<IndexMap<(&Cow<'static, str>, Course), bool>>();
|
||||||
|
|
||||||
let mut stack = visited.clone();
|
let mut stack = visited.clone();
|
||||||
for k in theme.keys() {
|
for k in theme.keys() {
|
||||||
|
|
Loading…
Reference in New Issue