summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bin.rs20
-rw-r--r--ui/src/conf.rs150
-rw-r--r--ui/src/conf/themes.rs50
3 files changed, 113 insertions, 107 deletions
diff --git a/src/bin.rs b/src/bin.rs
index 50cc96c1..ef3b7400 100644
--- a/src/bin.rs
+++ b/src/bin.rs
@@ -151,6 +151,18 @@ fn run_app() -> Result<()> {
"--version" | "-v" => {
args.version = true;
}
+ "--print-loaded-themes" => {
+ let s = ui::conf::FileSettings::new()?;
+ print!("{}", s.terminal.themes.to_string());
+ return Ok(());
+ }
+ "--print-default-theme" => {
+ print!(
+ "{}",
+ ui::conf::Theme::default().key_to_string("dark", false)
+ );
+ return Ok(());
+ }
e => match prev {
None => error_and_exit!("error: value without command {}", e),
Some(CreateConfig) if args.create_config.is_none() => {
@@ -179,11 +191,13 @@ fn run_app() -> Result<()> {
println!("");
println!("\t--help, -h\t\tshow this message and exit");
println!("\t--version, -v\t\tprint version and exit");
- println!("\t--create-config[ PATH]\tCreate a sample configuration file with available configuration options. If PATH is not specified, meli will try to create it in $XDG_CONFIG_HOME/meli/config");
+ println!("\t--create-config[ PATH]\tcreate a sample configuration file with available configuration options. If PATH is not specified, meli will try to create it in $XDG_CONFIG_HOME/meli/config");
println!(
- "\t--test-config PATH\tTest a configuration file for syntax issues or missing options."
+ "\t--test-config PATH\ttest a configuration file for syntax issues or missing options."
);
- println!("\t--config PATH, -c PATH\tUse specified configuration file");
+ println!("\t--config PATH, -c PATH\tuse specified configuration file");
+ println!("\t--print-loaded-themes\tprint loaded themes in full to stdout and exit.");
+ println!("\t--print-default-theme\tprint default theme in full to stdout and exit.");
return Ok(());
}
diff --git a/ui/src/conf.rs b/ui/src/conf.rs
index d8ae0cdd..975d1684 100644
--- a/ui/src/conf.rs
+++ b/ui/src/conf.rs
@@ -234,24 +234,24 @@ impl FileAccount {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct FileSettings {
- accounts: HashMap<String, FileAccount>,
+ pub accounts: HashMap<String, FileAccount>,
#[serde(default)]
- pager: PagerSettings,
+ pub pager: PagerSettings,
#[serde(default)]
- listing: ListingSettings,
+ pub listing: ListingSettings,
#[serde(default)]
- notifications: NotificationsSettings,
+ pub notifications: NotificationsSettings,
#[serde(default)]
- shortcuts: Shortcuts,
- composing: ComposingSettings,
+ pub shortcuts: Shortcuts,
+ pub composing: ComposingSettings,
#[serde(default)]
- tags: TagsSettings,
+ pub tags: TagsSettings,
#[serde(default)]
- pgp: PGPSettings,
+ pub pgp: PGPSettings,
#[serde(default)]
- terminal: TerminalSettings,
+ pub terminal: TerminalSettings,
#[serde(default)]
- plugins: HashMap<String, Plugin>,
+ pub plugins: HashMap<String, Plugin>,
}
#[derive(Debug, Clone, Default)]
@@ -336,70 +336,10 @@ impl FileSettings {
let path = config_path
.to_str()
.expect("Configuration file path was not valid UTF-8");
- FileSettings::validate(path)?;
- let mut s: FileSettings = toml::from_str(&pp::pp(path)?).map_err(|err| err.to_string())?;
- let Theme {
- light: default_light,
- dark: default_dark,
- ..
- } = Theme::default();
- for (k, v) in default_light.into_iter() {
- if !s.terminal.themes.light.contains_key(&k) {
- s.terminal.themes.light.insert(k, v);
- }
- }
- for theme in s.terminal.themes.other_themes.values_mut() {
- for (k, v) in default_dark.clone().into_iter() {
- if !theme.contains_key(&k) {
- theme.insert(k, v);
- }
- }
- }
- if let Ok(xdg_dirs) = xdg_dirs {
- for theme_folder in xdg_dirs.find_config_files("themes") {
- let read_dir = std::fs::read_dir(theme_folder)?;
- for theme in read_dir {
- let theme = theme?;
- if theme.path().is_file() {
- use std::os::unix::ffi::OsStrExt;
- let theme_name = if let Some(n) = theme
- .path()
- .file_stem()
- .map(|f| String::from_utf8_lossy(f.as_bytes()).into_owned())
- {
- n
- } else {
- continue;
- };
- let mut t: HashMap<std::borrow::Cow<'static, str>, ThemeAttributeInner> =
- toml::from_str(&pp::pp(theme.path())?).map_err(|err| {
- format!(
- "Could not parse theme in `{}`: {}",
- theme.path().display(),
- err.to_string()
- )
- })?;
- for (k, v) in default_dark.clone().into_iter() {
- if !t.contains_key(&k) {
- t.insert(k, v);
- }
- }
- s.terminal.themes.other_themes.insert(theme_name, t);
- }
- }
- }
- }
- for (k, v) in default_dark.into_iter() {
- if !s.terminal.themes.dark.contains_key(&k) {
- s.terminal.themes.dark.insert(k, v);
- }
- }
- s.terminal.themes.validate()?;
-
- Ok(s)
+ FileSettings::validate(path)
}
- pub fn validate(path: &str) -> Result<()> {
+ pub fn validate(path: &str) -> Result<Self> {
let s = pp::pp(path)?;
let mut s: FileSettings = toml::from_str(&s).map_err(|e| {
MeliError::new(format!(
@@ -420,35 +360,28 @@ impl FileSettings {
}
}
- if let Ok(xdg_dirs) = xdg::BaseDirectories::with_prefix("meli") {
- for theme_folder in xdg_dirs.find_config_files("themes") {
- let read_dir = std::fs::read_dir(theme_folder)?;
- for theme in read_dir {
- let theme = theme?;
- if theme.path().is_file() {
- use std::os::unix::ffi::OsStrExt;
- let theme_name = if let Some(n) = theme
- .path()
- .file_stem()
- .map(|f| String::from_utf8_lossy(f.as_bytes()).into_owned())
- {
- n
- } else {
- continue;
- };
- let t: HashMap<std::borrow::Cow<'static, str>, ThemeAttributeInner> =
- toml::from_str(&pp::pp(theme.path())?).map_err(|err| {
- format!(
- "Could not parse theme in `{}`: {}",
- theme.path().display(),
- err.to_string()
- )
- })?;
- s.terminal.themes.other_themes.insert(theme_name, t);
- }
+ let Theme {
+ light: default_light,
+ dark: default_dark,
+ ..
+ } = Theme::default();
+ for (k, v) in default_light.into_iter() {
+ if !s.terminal.themes.light.contains_key(&k) {
+ s.terminal.themes.light.insert(k, v);
+ }
+ }
+ for theme in s.terminal.themes.other_themes.values_mut() {
+ for (k, v) in default_dark.clone().into_iter() {
+ if !theme.contains_key(&k) {
+ theme.insert(k, v);
}
}
}
+ for (k, v) in default_dark.into_iter() {
+ if !s.terminal.themes.dark.contains_key(&k) {
+ s.terminal.themes.dark.insert(k, v);
+ }
+ }
match s.terminal.theme.as_str() {
"dark" | "light" => {}
t if s.terminal.themes.other_themes.contains_key(t) => {}
@@ -457,7 +390,8 @@ impl FileSettings {
}
}
- for (name, acc) in s.accounts {
+ s.terminal.themes.validate()?;
+ for (name, acc) in &s.accounts {
let FileAccount {
root_folder,
format,
@@ -471,11 +405,11 @@ impl FileSettings {
refresh_command: _,
index_style: _,
cache_type: _,
- } = acc;
+ } = acc.clone();
let lowercase_format = format.to_lowercase();
let s = AccountSettings {
- name,
+ name: name.to_string(),
root_folder,
format: format.clone(),
identity,
@@ -492,7 +426,7 @@ impl FileSettings {
backends.validate_config(&lowercase_format, &s)?;
}
- Ok(())
+ Ok(s)
}
}
@@ -832,8 +766,16 @@ mod pp {
path.as_ref().to_path_buf()
};
- let ret = pp_helper(&p_buf, 0);
+ let mut ret = pp_helper(&p_buf, 0)?;
drop(p_buf);
- ret
+ if let Ok(xdg_dirs) = xdg::BaseDirectories::with_prefix("meli") {
+ for theme_folder in xdg_dirs.find_config_files("themes") {
+ let read_dir = std::fs::read_dir(theme_folder)?;
+ for theme in read_dir {
+ ret.extend(pp_helper(&theme?.path(), 0)?.chars());
+ }
+ }
+ }
+ Ok(ret)
}
}
diff --git a/ui/src/conf/themes.rs b/ui/src/conf/themes.rs
index 8d2a3754..cbfd51ed 100644
--- a/ui/src/conf/themes.rs
+++ b/ui/src/conf/themes.rs
@@ -325,6 +325,56 @@ impl Theme {
Err(format!("Unrecognized theme keywords: {}", keys.join(", ")).into())
}
}
+
+ pub fn key_to_string(&self, key: &str, unlink: bool) -> String {
+ let theme = match key {
+ "light" => &self.light,
+ "dark" => &self.dark,
+ t => self.other_themes.get(t).unwrap_or(&self.dark),
+ };
+ let mut ret = String::new();
+ ret.extend(format!("[terminal.themes.{}]\n", key).chars());
+ if unlink {
+ for k in theme.keys() {
+ ret.extend(
+ format!(
+ "\"{}\" = {{ fg = {}, bg = {}, attrs = {} }}\n",
+ k,
+ toml::to_string(&unlink_fg(&theme, k)).unwrap(),
+ toml::to_string(&unlink_bg(&theme, k)).unwrap(),
+ toml::to_string(&unlink_attrs(&theme, k)).unwrap(),
+ )
+ .chars(),
+ );
+ }
+ } else {
+ for k in theme.keys() {
+ ret.extend(
+ format!(
+ "\"{}\" = {{ fg = {}, bg = {}, attrs = {} }}\n",
+ k,
+ toml::to_string(&theme[k].fg).unwrap(),
+ toml::to_string(&theme[k].bg).unwrap(),
+ toml::to_string(&theme[k].attrs).unwrap(),
+ )
+ .chars(),
+ );
+ }
+ }
+ ret
+ }
+ pub fn to_string(&self) -> String {
+ let mut ret = String::new();
+ ret.extend(self.key_to_string("dark", true).chars());
+
+ ret.push_str("\n\n");
+ ret.extend(self.key_to_string("light", true).chars());
+ for name in self.other_themes.keys() {
+ ret.push_str("\n\n");
+ ret.extend(self.key_to_string(name, true).chars());
+ }
+ ret
+ }
}
impl Default for Theme {