Skip to content

Commit

Permalink
List out available themes
Browse files Browse the repository at this point in the history
Improve error handling for theme listing
  • Loading branch information
gillespiecd committed Dec 2, 2020
1 parent 23a3183 commit cdfd6dd
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum VividError {
EmptyThemeFile,
CouldNotFindStyleFor(String),
UnknownColor(String),
InvalidFileName(String),
}

impl Display for VividError {
Expand All @@ -45,6 +46,9 @@ impl Display for VividError {
write!(fmt, "Could not find style for category '{}'", category)
}
VividError::UnknownColor(color) => write!(fmt, "Unknown color '{}'", color),
VividError::InvalidFileName(file_name) => {
write!(fmt, "Invalid file name '{}'", file_name)
}
}
}
}
Expand Down
40 changes: 37 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ mod types;
mod util;

use rust_embed::RustEmbed;
use std::env;
use std::path::{Path, PathBuf};
use std::process;
use std::{env, fs};

use clap::{
crate_description, crate_name, crate_version, App, AppSettings, Arg, ArgMatches, SubCommand,
Expand All @@ -23,6 +23,8 @@ use crate::theme::Theme;
#[folder = "themes/"]
struct ThemeAssets;

const THEME_PATH_SYSTEM: &str = "/usr/share/vivid/themes/";

fn get_user_config_path() -> PathBuf {
#[cfg(target_os = "macos")]
let config_dir_op = env::var_os("XDG_CONFIG_HOME")
Expand Down Expand Up @@ -61,6 +63,33 @@ fn load_filetypes_database(matches: &ArgMatches, user_config_path: &PathBuf) ->
}
}

fn available_theme_names(user_config_path: &PathBuf) -> Result<Vec<String>> {
let theme_path_user = user_config_path.clone().join("themes");
let theme_path_system = PathBuf::from(THEME_PATH_SYSTEM);
let theme_paths = util::get_all_existing_paths(&[&theme_path_user, &theme_path_system]);

let mut available_themes: Vec<String> = ThemeAssets::iter()
.map(|theme_name| theme_name.trim_end_matches(".yml").to_owned())
.collect::<Vec<_>>();

for path in theme_paths {
let dir = fs::read_dir(path).map_err(VividError::IoError)?;
for theme_file in dir {
let theme_name = theme_file
.map_err(VividError::IoError)?
.file_name()
.into_string()
.map_err(|n| {
VividError::InvalidFileName(n.as_os_str().to_string_lossy().into_owned())
})?;
available_themes.push(theme_name.trim_end_matches(".yml").to_owned());
}
}
available_themes.sort();
available_themes.dedup();
Ok(available_themes)
}

fn load_theme(
sub_matches: &ArgMatches,
user_config_path: &PathBuf,
Expand All @@ -82,7 +111,7 @@ fn load_theme(
theme_path_user.push(theme_file.clone());

let mut theme_path_system = PathBuf::new();
theme_path_system.push("/usr/share/vivid/themes/");
theme_path_system.push(THEME_PATH_SYSTEM);
theme_path_system.push(&theme_file);

let theme_path =
Expand Down Expand Up @@ -140,7 +169,8 @@ fn run() -> Result<()> {
SubCommand::with_name("preview")
.about("Preview a given theme")
.arg(Arg::with_name("theme").help("Name of the color theme")),
);
)
.subcommand(SubCommand::with_name("themes").about("Print a list of available themes"));

let matches = app.get_matches();
let color_mode = match matches.value_of("color-mode") {
Expand Down Expand Up @@ -180,6 +210,10 @@ fn run() -> Result<()> {
entry
);
}
} else if matches.subcommand_matches("themes").is_some() {
for theme in available_theme_names(&user_config_path)? {
println!("{}", theme);
}
}
Ok(())
}
Expand Down
4 changes: 4 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ pub fn transpose<T, E>(
pub fn get_first_existing_path<'a>(paths: &[&'a Path]) -> Option<&'a Path> {
paths.iter().find(|p| Path::exists(*p)).copied()
}

pub fn get_all_existing_paths<'a>(paths: &[&'a Path]) -> Vec<&'a Path> {
paths.iter().cloned().filter(|p| Path::exists(*p)).collect()
}

0 comments on commit cdfd6dd

Please # to comment.