diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 5274c2801..222f3880b 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -2930,7 +2930,29 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ aliases: &[], doc: "Change the editor theme (show current theme if no name specified).", fun: theme, - completer: CommandCompleter::positional(&[completers::theme]), + completer: CommandCompleter::positional(&[|_editor, input| completers::theme(_editor, input, "all")]), + signature: Signature { + positionals: (0, Some(1)), + ..Signature::DEFAULT + }, + }, + TypableCommand { + name: "theme-dark", + aliases: &[], + doc: "Change the editor theme to a dark theme (show current theme if no name specified).", + fun: theme, + completer: CommandCompleter::positional(&[|_editor, input| completers::theme(_editor, input, "dark")]), + signature: Signature { + positionals: (0, Some(1)), + ..Signature::DEFAULT + }, + }, + TypableCommand { + name: "theme-light", + aliases: &[], + doc: "Change the editor theme to a light theme (show current theme if no name specified).", + fun: theme, + completer: CommandCompleter::positional(&[|_editor, input| completers::theme(_editor, input, "light")]), signature: Signature { positionals: (0, Some(1)), ..Signature::DEFAULT diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index a76adbe21..a5cd7443e 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -399,13 +399,33 @@ pub mod completers { .collect() } - pub fn theme(_editor: &Editor, input: &str) -> Vec { - let mut names = theme::Loader::read_names(&helix_loader::config_dir().join("themes")); + pub fn theme(_editor: &Editor, input: &str, themes_type : &str) -> Vec { + let themes_dirs = match themes_type { + "dark" => vec!["themes/dark"], + "light" => vec!["themes/light"], + // The first element should not have any effect + _ => vec!["themes","themes/light","themes/dark"] + }; + + let mut names = Vec::new(); for rt_dir in helix_loader::runtime_dirs() { - names.extend(theme::Loader::read_names(&rt_dir.join("themes"))); - } - names.push("default".into()); - names.push("base16_default".into()); + for themes_dir in &themes_dirs { + names.extend(theme::Loader::read_names(&rt_dir.join(themes_dir))); + }; + }; + + for themes_dir in &themes_dirs { + names.extend(theme::Loader::read_names(&helix_loader::config_dir().join(themes_dir))); + }; + + match themes_type { + "light" => (), + "dark" => { names.push("default".into()); + }, + _ => { names.push("base16_default".into()); + names.push("default".into()); + } + }; names.sort(); names.dedup(); diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs index af8f03bca..5b23c0037 100644 --- a/helix-view/src/theme.rs +++ b/helix-view/src/theme.rs @@ -40,17 +40,25 @@ pub struct Loader { /// Theme directories to search from highest to lowest priority theme_dirs: Vec, } + impl Loader { /// Creates a new loader that can load themes from multiple directories. /// /// The provided directories should be ordered from highest to lowest priority. - /// The directories will have their "themes" subdirectory searched. + /// The directories will have their "themes/dark", "themes/light" and "themes" subdirectory searched. pub fn new(dirs: &[PathBuf]) -> Self { + let theme_dirs: Vec<_> = dirs.iter() + .flat_map(|p| { + vec![p.join("themes/dark"), p.join("themes/light"), p.join("themes")] + }) + .collect(); + Self { - theme_dirs: dirs.iter().map(|p| p.join("themes")).collect(), + theme_dirs, } } + /// Loads a theme searching directories in priority order. pub fn load(&self, name: &str) -> Result { let (theme, warnings) = self.load_with_warnings(name)?;