diff --git a/src/features/hyperlinks.rs b/src/features/hyperlinks.rs index aac32210e..118d83557 100644 --- a/src/features/hyperlinks.rs +++ b/src/features/hyperlinks.rs @@ -1,6 +1,5 @@ use std::borrow::Cow; use std::path::Path; -use std::str::FromStr; use lazy_static::lazy_static; use regex::{Captures, Regex}; @@ -33,8 +32,10 @@ pub fn format_commit_line_with_osc8_commit_hyperlink<'a>( format_osc8_hyperlink(&commit_link_format.replace("{commit}", commit), commit); format!("{prefix}{formatted_commit}{suffix}") }) - } else if let Some(GitConfigEntry::GitRemote(repo)) = - config.git_config.as_ref().and_then(get_remote_url) + } else if let Some(GitConfigEntry::GitRemote(repo)) = config + .git_config + .as_ref() + .and_then(GitConfig::get_remote_url) { COMMIT_LINE_REGEX.replace(line, |captures: &Captures| { format_commit_line_captures_with_osc8_commit_hyperlink(captures, &repo) @@ -44,20 +45,6 @@ pub fn format_commit_line_with_osc8_commit_hyperlink<'a>( } } -fn get_remote_url(git_config: &GitConfig) -> Option { - git_config - .repo - .as_ref()? - .find_remote("origin") - .ok()? - .url() - .and_then(|url| { - GitRemoteRepo::from_str(url) - .ok() - .map(GitConfigEntry::GitRemote) - }) -} - /// Create a file hyperlink, displaying `text`. pub fn format_osc8_file_hyperlink<'a, P>( absolute_path: P, diff --git a/src/git_config/mod.rs b/src/git_config/mod.rs index 228fd4d01..8246df4a9 100644 --- a/src/git_config/mod.rs +++ b/src/git_config/mod.rs @@ -7,14 +7,15 @@ use regex::Regex; use std::collections::HashMap; #[cfg(test)] use std::path::Path; +use std::str::FromStr; use lazy_static::lazy_static; pub struct GitConfig { - pub config: git2::Config, + config: git2::Config, config_from_env_var: HashMap, pub enabled: bool, - pub repo: Option, + repo: Option, // To make GitConfig cloneable when testing (in turn to make Config cloneable): #[cfg(test)] path: std::path::PathBuf, @@ -94,6 +95,31 @@ impl GitConfig { None } } + + pub fn get_remote_url(&self) -> Option { + self.repo + .as_ref()? + .find_remote("origin") + .ok()? + .url() + .and_then(|url| { + GitRemoteRepo::from_str(url) + .ok() + .map(GitConfigEntry::GitRemote) + }) + } + + pub fn for_each(&self, regex: &str, mut f: F) + where + F: FnMut(&str, Option<&str>), + { + let mut entries = self.config.entries(Some(regex)).unwrap(); + while let Some(entry) = entries.next() { + let entry = entry.unwrap(); + let name = entry.name().unwrap(); + f(name, entry.value()); + } + } } fn parse_config_from_env_var(env: &DeltaEnv) -> HashMap { diff --git a/src/options/get.rs b/src/options/get.rs index 53a4d635f..2ee3ee1b9 100644 --- a/src/options/get.rs +++ b/src/options/get.rs @@ -1,5 +1,3 @@ -use lazy_static::lazy_static; -use regex::Regex; use std::collections::HashMap; use crate::cli; @@ -40,25 +38,21 @@ where T::get_option_value(option_name, builtin_features, opt, git_config) } -lazy_static! { - static ref GIT_CONFIG_THEME_REGEX: Regex = Regex::new(r"^delta\.(.+)\.(light|dark)$").unwrap(); -} +static GIT_CONFIG_THEME_REGEX: &str = r#"^delta\.(.+)\.(light|dark)$"#; pub fn get_themes(git_config: Option) -> Vec { let mut themes: Vec = Vec::new(); let git_config = git_config.unwrap(); - let mut entries = git_config.config.entries(None).unwrap(); - while let Some(e) = entries.next() { - let entry = e.unwrap(); - let entry_name = entry.name().unwrap(); - let caps = GIT_CONFIG_THEME_REGEX.captures(entry_name); - if let Some(caps) = caps { - let name = caps.get(1).map_or("", |m| m.as_str()).to_string(); - if !themes.contains(&name) { - themes.push(name) + git_config.for_each(GIT_CONFIG_THEME_REGEX, |name, _| { + if let Some(name) = name.strip_prefix("delta.") { + if let Some((name, _)) = name.rsplit_once('.') { + let name = name.to_owned(); + if !themes.contains(&name) { + themes.push(name); + } } } - } + }); themes.sort_by_key(|a| a.to_lowercase()); themes }