Add 2 theme-related cli flags
parent
5230ce2d03
commit
8ec82b836a
20
src/bin.rs
20
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(());
|
||||
}
|
||||
|
||||
|
|
150
ui/src/conf.rs
150
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue