Skip to content

Commit 3bed178

Browse files
committed
Add OSC 8 link support to filepath in headers
1 parent b2454ca commit 3bed178

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

src/display/inline.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,18 @@ pub(crate) fn print(
6565
let opposite_to_rhs = opposite_positions(rhs_mps);
6666

6767
for (i, hunk) in hunks.iter().enumerate() {
68+
let first_line = hunk
69+
.novel_lhs
70+
.iter()
71+
.min()
72+
.or_else(|| hunk.novel_rhs.iter().min())
73+
.copied();
74+
6875
println!(
6976
"{}",
7077
style::header(
7178
display_path,
79+
first_line,
7280
extra_info.as_ref(),
7381
i + 1,
7482
hunks.len(),

src/display/side_by_side.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ fn display_single_column(
9090
let mut header_line = String::new();
9191
header_line.push_str(&style::header(
9292
display_path,
93+
Some(0.into()),
9394
old_path,
9495
1,
9596
1,
@@ -598,10 +599,18 @@ pub(crate) fn print(
598599
);
599600

600601
for (i, hunk) in hunks.iter().enumerate() {
602+
let first_line = hunk
603+
.novel_rhs
604+
.iter()
605+
.min()
606+
.or_else(|| hunk.novel_lhs.iter().min())
607+
.copied();
608+
601609
println!(
602610
"{}",
603611
style::header(
604612
display_path,
613+
first_line,
605614
old_path,
606615
i + 1,
607616
hunks.len(),

src/display/style.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Apply colours and styling to strings.
22
33
use std::cmp::{max, min};
4+
use std::path::Path;
45

56
use line_numbers::{LineNumber, SingleLineSpan};
67
use owo_colors::{OwoColorize, Style};
@@ -13,6 +14,12 @@ use crate::options::DisplayOptions;
1314
use crate::parse::syntax::{AtomKind, MatchKind, MatchedPos, StringKind, TokenKind};
1415
use crate::summary::FileFormat;
1516

17+
// OSC 8 hyperlink escape sequences
18+
// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
19+
const OSC_8_START: &str = "\x1b]8;;";
20+
const OSC_8_ST: &str = "\x1b\\";
21+
const OSC_8_END: &str = "\x1b]8;;\x1b\\";
22+
1623
#[derive(Clone, Copy, Debug)]
1724
pub(crate) enum BackgroundColor {
1825
Dark,
@@ -536,8 +543,22 @@ pub(crate) fn apply_line_number_color(
536543
}
537544
}
538545

546+
fn make_path_hyperlink(display_path: &str, line_number: Option<LineNumber>) -> String {
547+
let Ok(canonical_path) = Path::new(display_path).canonicalize() else {
548+
return display_path.to_owned();
549+
};
550+
551+
let mut url = format!("file://{}", canonical_path.display());
552+
if let Some(line_num) = line_number {
553+
url.push_str(&format!("#{}", line_num.0 + 1));
554+
}
555+
556+
format!("{OSC_8_START}{url}{OSC_8_ST}{display_path}{OSC_8_END}")
557+
}
558+
539559
pub(crate) fn header(
540560
display_path: &str,
561+
first_line_number: Option<LineNumber>,
541562
extra_info: Option<&String>,
542563
hunk_num: usize,
543564
hunk_total: usize,
@@ -550,8 +571,14 @@ pub(crate) fn header(
550571
format!("{}/{} --- ", hunk_num, hunk_total)
551572
};
552573

574+
let display_path_with_link = if display_options.use_color {
575+
make_path_hyperlink(display_path, first_line_number)
576+
} else {
577+
display_path.to_owned()
578+
};
579+
553580
let display_path_pretty = apply_header_color(
554-
display_path,
581+
&display_path_with_link,
555582
display_options.use_color,
556583
display_options.background_color,
557584
hunk_num,

src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,7 @@ fn print_diff_result(display_options: &DisplayOptions, summary: &DiffResult) {
884884
"{}",
885885
display::style::header(
886886
&summary.display_path,
887+
None,
887888
summary.extra_info.as_ref(),
888889
1,
889890
1,
@@ -911,6 +912,7 @@ fn print_diff_result(display_options: &DisplayOptions, summary: &DiffResult) {
911912
"{}",
912913
display::style::header(
913914
&summary.display_path,
915+
None,
914916
summary.extra_info.as_ref(),
915917
1,
916918
1,
@@ -966,6 +968,7 @@ fn print_diff_result(display_options: &DisplayOptions, summary: &DiffResult) {
966968
"{}",
967969
display::style::header(
968970
&summary.display_path,
971+
None,
969972
summary.extra_info.as_ref(),
970973
1,
971974
1,
@@ -1014,6 +1017,7 @@ fn print_diff_result(display_options: &DisplayOptions, summary: &DiffResult) {
10141017
"{}",
10151018
display::style::header(
10161019
&summary.display_path,
1020+
None,
10171021
summary.extra_info.as_ref(),
10181022
1,
10191023
1,

0 commit comments

Comments
 (0)