diff --git a/src/delta.rs b/src/delta.rs index 80c5d7a85..7baef3745 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -9,6 +9,7 @@ use crate::config::delta_unreachable; use crate::config::Config; use crate::config::GrepType; use crate::features; +use crate::git_config::GitRemoteRepo; use crate::handlers::grep; use crate::handlers::hunk_header::{AmbiguousDiffMinusCounter, ParsedHunkHeader}; use crate::handlers::{self, merge_conflict}; @@ -112,6 +113,7 @@ pub struct StateMachine<'a> { pub handled_diff_header_header_line_file_pair: Option<(String, String)>, pub blame_key_colors: HashMap, pub minus_line_counter: AmbiguousDiffMinusCounter, + pub git_remote_repo: Option, } pub fn delta(lines: ByteLines, writer: &mut dyn Write, config: &Config) -> std::io::Result<()> @@ -140,6 +142,7 @@ impl<'a> StateMachine<'a> { config, blame_key_colors: HashMap::new(), minus_line_counter: AmbiguousDiffMinusCounter::not_needed(), + git_remote_repo: features::hyperlinks::remote_from_config(&config.git_config()), } } @@ -248,7 +251,7 @@ impl<'a> StateMachine<'a> { writeln!( self.painter.writer, "{}", - format_raw_line(&self.raw_line, self.config) + format_raw_line(&self.raw_line, self.config, &self.git_remote_repo) )?; let handled_line = true; Ok(handled_line) @@ -265,9 +268,13 @@ impl<'a> StateMachine<'a> { /// If output is going to a tty, emit hyperlinks if requested. // Although raw output should basically be emitted unaltered, we do this. -pub fn format_raw_line<'a>(line: &'a str, config: &Config) -> Cow<'a, str> { +pub fn format_raw_line<'a>( + line: &'a str, + config: &Config, + repo: &Option, +) -> Cow<'a, str> { if config.hyperlinks && io::stdout().is_terminal() { - features::hyperlinks::format_commit_line_with_osc8_commit_hyperlink(line, config) + features::hyperlinks::format_commit_line_with_osc8_commit_hyperlink(line, config, repo) } else { Cow::from(line) } diff --git a/src/features/hyperlinks.rs b/src/features/hyperlinks.rs index 102e68b8c..b40eeef6f 100644 --- a/src/features/hyperlinks.rs +++ b/src/features/hyperlinks.rs @@ -21,9 +21,7 @@ pub fn make_feature() -> Vec<(String, OptionValueFunction)> { #[cfg(test)] pub fn remote_from_config(_: &Option<&GitConfig>) -> Option { - Some(GitRemoteRepo::GitHub { - slug: "dandavison/delta".to_string(), - }) + GitRemoteRepo::for_testing() } #[cfg(not(test))] @@ -41,6 +39,7 @@ lazy_static! { pub fn format_commit_line_with_osc8_commit_hyperlink<'a>( line: &'a str, config: &Config, + cached_repo: &Option, ) -> Cow<'a, str> { // Given matches in a line, m = matches[0] and pos = 0: store line[pos..m.start()] first, then // store the T(line[m.start()..m.end()]) match transformation, then set pos = m.end(). @@ -80,7 +79,7 @@ pub fn format_commit_line_with_osc8_commit_hyperlink<'a>( .with_input(line, &first_match, &mut matches); return Cow::from(result); } - } else if let Some(repo) = remote_from_config(&config.git_config()) { + } else if let Some(repo) = cached_repo { let mut matches = COMMIT_HASH_REGEX.find_iter(line); if let Some(first_match) = matches.next() { let result = HyperlinkCommits(|commit_hash| repo.format_commit_url(commit_hash)) @@ -144,27 +143,28 @@ pub mod tests { #[test] fn test_formatted_hyperlinks() { + let remote = GitRemoteRepo::for_testing(); let config = make_config_from_args(&["--hyperlinks-commit-link-format", "HERE:{commit}"]); - let line = "001234abcdf"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!( result, "\u{1b}]8;;HERE:001234abcdf\u{1b}\\001234abcdf\u{1b}]8;;\u{1b}\\", ); let line = "a2272718f0b398e48652ace17fca85c1962b3fc22"; // length: 41 > 40 - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!(result, "a2272718f0b398e48652ace17fca85c1962b3fc22",); let line = "a2272718f0+b398e48652ace17f,ca85c1962b3fc2"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!(result, "\u{1b}]8;;HERE:a2272718f0\u{1b}\\a2272718f0\u{1b}]8;;\u{1b}\\+\u{1b}]8;;\ HERE:b398e48652ace17f\u{1b}\\b398e48652ace17f\u{1b}]8;;\u{1b}\\,\u{1b}]8;;HERE:ca85c1962b3fc2\ \u{1b}\\ca85c1962b3fc2\u{1b}]8;;\u{1b}\\"); let line = "This 01234abcdf Hash"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!( result, "This \u{1b}]8;;HERE:01234abcdf\u{1b}\\01234abcdf\u{1b}]8;;\u{1b}\\ Hash", @@ -172,7 +172,7 @@ pub mod tests { let line = "Another 01234abcdf hash but also this one: dc623b084ad2dd14fe5d90189cacad5d49bfbfd3!"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!( result, "Another \u{1b}]8;;HERE:01234abcdf\u{1b}\\01234abcdf\u{1b}]8;;\u{1b}\\ hash but \ @@ -181,7 +181,7 @@ pub mod tests { ); let line = "01234abcdf 03043baf30 12abcdef0 12345678"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!( result, "\u{1b}]8;;HERE:01234abcdf\u{1b}\\01234abcdf\u{1b}]8;;\u{1b}\\ \u{1b}]8;;\ @@ -194,9 +194,10 @@ pub mod tests { fn test_hyperlinks_to_repo() { let mut config = make_config_from_args(&["--hyperlinks"]); config.git_config = GitConfig::for_testing(); + let remote = GitRemoteRepo::for_testing(); let line = "This a589ff9debaefdd delta commit"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!( result, "This \u{1b}]8;;https://github.com/dandavison/delta/commit/a589ff9debaefdd\u{1b}\ @@ -205,7 +206,7 @@ pub mod tests { let line = "Another a589ff9debaefdd hash but also this one: c5696757c0827349a87daa95415656!"; - let result = format_commit_line_with_osc8_commit_hyperlink(line, &config); + let result = format_commit_line_with_osc8_commit_hyperlink(line, &config, &remote); assert_eq!( result, "Another \u{1b}]8;;https://github.com/dandavison/delta/commit/a589ff9debaefdd\ diff --git a/src/git_config/remote.rs b/src/git_config/remote.rs index ed60e8ad4..6737a5031 100644 --- a/src/git_config/remote.rs +++ b/src/git_config/remote.rs @@ -31,6 +31,13 @@ impl GitRemoteRepo { } } } + + #[cfg(test)] + pub fn for_testing() -> Option { + Some(GitRemoteRepo::GitHub { + slug: "dandavison/delta".to_string(), + }) + } } lazy_static! { diff --git a/src/handlers/blame.rs b/src/handlers/blame.rs index 47bda3a61..c4d85ddc4 100644 --- a/src/handlers/blame.rs +++ b/src/handlers/blame.rs @@ -12,6 +12,7 @@ use crate::delta::{self, State, StateMachine}; use crate::fatal; use crate::format::{self, FormatStringSimple, Placeholder}; use crate::format::{make_placeholder_regex, parse_line_number_format}; +use crate::git_config::GitRemoteRepo; use crate::paint::{self, BgShouldFill, StyleSectionSpecifier}; use crate::style::Style; use crate::utils::process; @@ -48,7 +49,7 @@ impl StateMachine<'_> { false, ); let mut formatted_blame_metadata = - format_blame_metadata(&format_data, &blame, self.config); + format_blame_metadata(&format_data, &blame, self.config, &self.git_remote_repo); let key = formatted_blame_metadata.clone(); let is_repeat = previous_key.as_deref() == Some(&key); if is_repeat { @@ -262,6 +263,7 @@ pub fn format_blame_metadata( format_data: &[format::FormatStringPlaceholderData], blame: &BlameLine, config: &config::Config, + repo: &Option, ) -> String { let mut s = String::new(); let mut suffix = ""; @@ -279,7 +281,9 @@ pub fn format_blame_metadata( })) } Some(Placeholder::Str("author")) => Some(Cow::from(blame.author)), - Some(Placeholder::Str("commit")) => Some(delta::format_raw_line(blame.commit, config)), + Some(Placeholder::Str("commit")) => { + Some(delta::format_raw_line(blame.commit, config, repo)) + } None => None, _ => unreachable!("Unexpected `git blame` input"), }; @@ -421,7 +425,8 @@ mod tests { let blame = make_blame_line_with_time("1996-12-19T16:39:57-08:00"); let config = integration_test_utils::make_config_from_args(&[]); let regex = Regex::new(r"^\d+ years ago$").unwrap(); - let result = format_blame_metadata(&[format_data], &blame, &config); + let remote: Option = None; + let result = format_blame_metadata(&[format_data], &blame, &config, &remote); assert!(regex.is_match(result.trim())); } @@ -432,7 +437,8 @@ mod tests { let config = integration_test_utils::make_config_from_args(&[ "--blame-timestamp-output-format=%Y-%m-%d %H:%M", ]); - let result = format_blame_metadata(&[format_data], &blame, &config); + let remote: Option = None; + let result = format_blame_metadata(&[format_data], &blame, &config, &remote); assert_eq!(result.trim(), "1996-12-19 16:39"); } @@ -444,11 +450,12 @@ mod tests { let format_data1 = make_format_data_with_placeholder("author"); let blame1 = make_blame_line_with_author("E\u{301}dith Piaf"); - let result1 = format_blame_metadata(&[format_data1], &blame1, &config); + let remote: Option = None; + let result1 = format_blame_metadata(&[format_data1], &blame1, &config, &remote); let format_data2 = make_format_data_with_placeholder("author"); let blame2 = make_blame_line_with_author("Edith Piaf"); - let result2 = format_blame_metadata(&[format_data2], &blame2, &config); + let result2 = format_blame_metadata(&[format_data2], &blame2, &config, &remote); assert_eq!( count_trailing_spaces(result1), diff --git a/src/handlers/commit_meta.rs b/src/handlers/commit_meta.rs index aee18c91b..6d8f00f4e 100644 --- a/src/handlers/commit_meta.rs +++ b/src/handlers/commit_meta.rs @@ -37,10 +37,12 @@ impl StateMachine<'_> { features::hyperlinks::format_commit_line_with_osc8_commit_hyperlink( &self.line, self.config, + &self.git_remote_repo, ), features::hyperlinks::format_commit_line_with_osc8_commit_hyperlink( &self.raw_line, self.config, + &self.git_remote_repo, ), ) } else {