Skip to content

Commit 200ab28

Browse files
committed
feat: Add support for hyperlinks in snippet origin
1 parent 577b8fa commit 200ab28

5 files changed

Lines changed: 43 additions & 2 deletions

File tree

src/renderer/render.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,11 @@ fn render_origin(
485485
_ => origin.path.to_string(),
486486
};
487487

488+
let link = Hyperlink {
489+
url: origin.url.as_deref(),
490+
};
491+
let str = format!("{link}{str}{link:#}");
492+
488493
buffer.append(buffer_msg_line_offset, &str, ElementStyle::LineAndColumn);
489494
if !renderer.short_message {
490495
for _ in 0..max_line_num_len {
@@ -552,6 +557,11 @@ fn render_snippet_annotations(
552557
}
553558
}
554559
}
560+
561+
if let Some(url) = &snippet.url {
562+
origin.url = Some(Cow::Borrowed(url));
563+
}
564+
555565
let buffer_msg_line_offset = buffer.num_lines();
556566
render_origin(
557567
renderer,

src/snippet.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ pub struct Snippet<'a, T> {
227227
pub(crate) line_start: usize,
228228
pub(crate) source: Cow<'a, str>,
229229
pub(crate) markers: Vec<T>,
230+
pub(crate) url: Option<Cow<'a, str>>,
230231
pub(crate) fold: bool,
231232
}
232233

@@ -246,6 +247,7 @@ impl<'a, T: Clone> Snippet<'a, T> {
246247
line_start: 1,
247248
source: source.into(),
248249
markers: vec![],
250+
url: None,
249251
fold: true,
250252
}
251253
}
@@ -271,6 +273,19 @@ impl<'a, T: Clone> Snippet<'a, T> {
271273
self
272274
}
273275

276+
/// The URL to the [`source`][Self::source]. Can be a `file://` URL.
277+
///
278+
/// Make sure to follow [the OSC 8 reference document][OSC-8], and in
279+
/// particular the [`file://` URIs and the hostname][OSC-8-file-URIs] when
280+
/// generating a `file://` URL.
281+
///
282+
/// [OSC-8]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
283+
/// [OSC-8-file-URIs]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#file-uris-and-the-hostname
284+
pub fn path_url(mut self, url: impl Into<OptionCow<'a>>) -> Self {
285+
self.url = url.into().0;
286+
self
287+
}
288+
274289
/// Control whether lines without [`Annotation`]s are shown
275290
///
276291
/// The default is `fold(true)`, collapsing uninteresting lines.
@@ -487,6 +502,7 @@ pub struct Origin<'a> {
487502
pub(crate) path: Cow<'a, str>,
488503
pub(crate) line: Option<usize>,
489504
pub(crate) char_column: Option<usize>,
505+
pub(crate) url: Option<Cow<'a, str>>,
490506
}
491507

492508
impl<'a> Origin<'a> {
@@ -502,6 +518,7 @@ impl<'a> Origin<'a> {
502518
path: path.into(),
503519
line: None,
504520
char_column: None,
521+
url: None,
505522
}
506523
}
507524

@@ -522,6 +539,19 @@ impl<'a> Origin<'a> {
522539
self.char_column = Some(char_column);
523540
self
524541
}
542+
543+
/// The URL to the origin. Can be a `file://` URL.
544+
///
545+
/// Make sure to follow [the OSC 8 reference document][OSC-8], and in
546+
/// particular the [`file://` URIs and the hostname][OSC-8-file-URIs] when
547+
/// generating a `file://` URL.
548+
///
549+
/// [OSC-8]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
550+
/// [OSC-8-file-URIs]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#file-uris-and-the-hostname
551+
pub fn path_url(mut self, uri: impl Into<Cow<'a, str>>) -> Self {
552+
self.url = Some(uri.into());
553+
self
554+
}
525555
}
526556

527557
impl<'a> From<Cow<'a, str>> for Origin<'a> {

tests/hyperlink.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fn simple() {
1616
Snippet::source(source)
1717
.line_start(26)
1818
.path("examples/footer.rs")
19+
.path_url("file://localhost/home/user/rust/file.rs")
1920
.annotation(AnnotationKind::Primary.span(193..195).label(
2021
"expected struct `annotate_snippets::snippet::Slice`, found reference",
2122
))

tests/hyperlink_expected_type.ascii.term.svg

Lines changed: 1 addition & 1 deletion
Loading

tests/hyperlink_expected_type.unicode.term.svg

Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)