summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-05-25 23:28:53 -0400
committerGitHub <noreply@github.com>2021-05-25 23:28:53 -0400
commitebe08f9a6d7156e6e1f4504f38f4652426fdb50e (patch)
tree81f209d9ffcac4677fffb64ce0457b97533903b8
parent6be96be6b9af9ababc67835a35d8685d2fc6867d (diff)
Add hyperlinks-commit-link-format option (#614)
* Refactor: hyperlinks utility * Add hyperlinks-commit-link-format option Fixes #613
-rw-r--r--src/cli.rs25
-rw-r--r--src/config.rs2
-rw-r--r--src/features/hyperlinks.rs25
-rw-r--r--src/options/set.rs1
-rw-r--r--src/tests/test_example_diffs.rs17
5 files changed, 54 insertions, 16 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 40629bca..8a8c162f 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -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>