diff options
author | Dan Davison <dandavison7@gmail.com> | 2021-05-25 23:28:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-25 23:28:53 -0400 |
commit | ebe08f9a6d7156e6e1f4504f38f4652426fdb50e (patch) | |
tree | 81f209d9ffcac4677fffb64ce0457b97533903b8 | |
parent | 6be96be6b9af9ababc67835a35d8685d2fc6867d (diff) |
Add hyperlinks-commit-link-format option (#614)
* Refactor: hyperlinks utility
* Add hyperlinks-commit-link-format option
Fixes #613
-rw-r--r-- | src/cli.rs | 25 | ||||
-rw-r--r-- | src/config.rs | 2 | ||||
-rw-r--r-- | src/features/hyperlinks.rs | 25 | ||||
-rw-r--r-- | src/options/set.rs | 1 | ||||
-rw-r--r-- | src/tests/test_example_diffs.rs | 17 |
5 files changed, 54 insertions, 16 deletions
@@ -372,14 +372,23 @@ pub struct Opt { /// (overline), or the combination 'ul ol'. pub file_decoration_style: String, - /// Format string for file hyperlinks. The placeholders "{path}" and "{line}" will be replaced - /// by the absolute file path and the line number, respectively. The default value of this - /// option creates hyperlinks using standard file URLs; your operating system should open these - /// in the application registered for that file type. However, these do not make use of the - /// line number. In order for the link to open the file at the correct line number, you could - /// use a custom URL format such as "file-line://{path}:{line}" and register an application to - /// handle the custom "file-line" URL scheme by opening the file in your editor/IDE at the - /// indicated line number. See https://github.com/dandavison/open-in-editor for an example. + /// Format string for commit hyperlinks (requires --hyperlinks). The + /// placeholder "{commit}" will be replaced by the commit hash. For example: + /// --hyperlinks-commit-link-format='https://mygitrepo/{commit}/' + #[structopt(long = "hyperlinks-commit-link-format")] + pub hyperlinks_commit_link_format: Option<String>, + + /// Format string for file hyperlinks (requires --hyperlinks). The + /// placeholders "{path}" and "{line}" will be replaced by the absolute file + /// path and the line number, respectively. The default value of this option + /// creates hyperlinks using standard file URLs; your operating system + /// should open these in the application registered for that file type. + /// However, these do not make use of the line number. In order for the link + /// to open the file at the correct line number, you could use a custom URL + /// format such as "file-line://{path}:{line}" and register an application + /// to handle the custom "file-line" URL scheme by opening the file in your + /// editor/IDE at the indicated line number. See + /// https://github.com/dandavison/open-in-editor for an example. #[structopt(long = "hyperlinks-file-link-format", default_value = "file://{path}")] pub hyperlinks_file_link_format: String, diff --git a/src/config.rs b/src/config.rs index 8d72fb33..0b8ab6d1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -41,6 +41,7 @@ pub struct Config { pub hunk_header_style_include_file_path: bool, pub hunk_header_style_include_line_number: bool, pub hyperlinks: bool, + pub hyperlinks_commit_link_format: Option<String>, pub hyperlinks_file_link_format: String, pub inspect_raw_lines: cli::InspectRawLines, pub keep_plus_minus_markers: bool, @@ -220,6 +221,7 @@ impl From<cli::Opt> for Config { .split(' ') .any(|s| s == "line-number"), hyperlinks: opt.hyperlinks, + hyperlinks_commit_link_format: opt.hyperlinks_commit_link_format, hyperlinks_file_link_format: opt.hyperlinks_file_link_format, inspect_raw_lines: opt.computed.inspect_raw_lines, keep_plus_minus_markers: opt.keep_plus_minus_markers, diff --git a/src/features/hyperlinks.rs b/src/features/hyperlinks.rs index d59f5e9b..bf0c2354 100644 --- a/src/features/hyperlinks.rs +++ b/src/features/hyperlinks.rs @@ -22,7 +22,12 @@ pub fn format_commit_line_with_osc8_commit_hyperlink<'a>( line: &'a str, config: &Config, ) -> Cow<'a, str> { - if let Some(GitConfigEntry::GitRemote(GitRemoteRepo::GitHubRepo(repo))) = + if let Some(commit_link_format) = &config.hyperlinks_commit_link_format { + COMMIT_LINE_REGEX.replace(line, |captures: &Captures| { + let commit = captures.get(2).unwrap().as_str(); + format_osc8_hyperlink(&commit_link_format.replace("{commit}", commit), commit) + }) + } else if let Some(GitConfigEntry::GitRemote(GitRemoteRepo::GitHubRepo(repo))) = config.git_config_entries.get("remote.origin.url") { COMMIT_LINE_REGEX.replace(line, |captures: &Captures| { @@ -51,18 +56,22 @@ pub fn format_osc8_file_hyperlink<'a>( } else { url = url.replace("{line}", "") }; - Cow::from(format!( - "{osc}8;;{url}{st}{text}{osc}8;;{st}", - url = url, - text = text, - osc = "\x1b]", - st = "\x1b\\" - )) + Cow::from(format_osc8_hyperlink(&url, text)) } else { Cow::from(relative_path) } } +fn format_osc8_hyperlink(url: &str, text: &str) -> String { + format!( + "{osc}8;;{url}{st}{text}{osc}8;;{st}", + url = url, + text = text, + osc = "\x1b]", + st = "\x1b\\" + ) +} + lazy_static! { static ref COMMIT_LINE_REGEX: Regex = Regex::new("(.* )([0-9a-f]{40})(.*)").unwrap(); } diff --git a/src/options/set.rs b/src/options/set.rs index b27907e0..a737fd4b 100644 --- a/src/options/set.rs +++ b/src/options/set.rs @@ -142,6 +142,7 @@ pub fn set_options( hunk_header_line_number_style, hunk_header_style, hyperlinks, + hyperlinks_commit_link_format, hyperlinks_file_link_format, inspect_raw_lines, keep_plus_minus_markers, diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs index 82b12f52..7c7192e6 100644 --- a/src/tests/test_example_diffs.rs +++ b/src/tests/test_example_diffs.rs @@ -1591,6 +1591,23 @@ src/align.rs:71: impl<'a> Alignment<'a> { │ assert!(output.contains(r"src/delta.rs: mode -x")); } + #[test] + fn test_hyperlinks_commit_link_format() { + let config = integration_test_utils::make_config_from_args(&[ + // If commit-style is not set then the commit line is handled in raw + // mode, in which case we only format hyperlinks if output is a tty; + // this causes the test to fail on Github Actions, but pass locally + // if output is left going to the screen. + "--commit-style", + "blue", + "--hyperlinks", + "--hyperlinks-commit-link-format", + "https://invent.kde.org/utilities/konsole/-/commit/{commit}", + ]); + let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); + assert!(output.contains(r"https://invent.kde.org/utilities/konsole/-/commit/94907c0f136f46dc46ffae2dc92dca9af7eb7c2e")); + } + const GIT_DIFF_SINGLE_HUNK: &str = "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e Author: Dan Davison <dandavison7@gmail.com> |