Skip to content

Commit 830fa88

Browse files
committed
feat: Add support for hyperlinks in snippet origin
1 parent 03bc94d commit 830fa88

5 files changed

Lines changed: 56 additions & 2 deletions

File tree

src/renderer/render.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,23 @@ fn render_origin(
488488
_ => origin.path.to_string(),
489489
};
490490

491+
if let Some(url) = &origin.url {
492+
let url = normalize_whitespace(url);
493+
buffer.append(
494+
buffer_msg_line_offset,
495+
&format!("\x1B]8;;{url}\x1B\\"),
496+
ElementStyle::LineAndColumn,
497+
);
498+
}
491499
buffer.append(buffer_msg_line_offset, &str, ElementStyle::LineAndColumn);
500+
if origin.url.is_some() {
501+
buffer.append(
502+
buffer_msg_line_offset,
503+
"\x1B]8;;\x1B\\",
504+
ElementStyle::LineAndColumn,
505+
);
506+
}
507+
492508
if !renderer.short_message {
493509
for _ in 0..max_line_num_len {
494510
buffer.prepend(buffer_msg_line_offset, " ", ElementStyle::NoStyle);
@@ -555,6 +571,11 @@ fn render_snippet_annotations(
555571
}
556572
}
557573
}
574+
575+
if let Some(url) = &snippet.url {
576+
origin.url = Some(Cow::Borrowed(url));
577+
}
578+
558579
let buffer_msg_line_offset = buffer.num_lines();
559580
render_origin(
560581
renderer,

src/snippet.rs

Lines changed: 32 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,20 @@ 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+
/// <div class="warning">
279+
///
280+
/// Text passed to this function is considered "untrusted input", as such
281+
/// all text is passed through a normalization function. Pre-styled text is
282+
/// not allowed to be passed to this function.
283+
///
284+
/// </div>
285+
pub fn path_url(mut self, url: impl Into<OptionCow<'a>>) -> Self {
286+
self.url = url.into().0;
287+
self
288+
}
289+
274290
/// Control whether lines without [`Annotation`]s are shown
275291
///
276292
/// The default is `fold(true)`, collapsing uninteresting lines.
@@ -487,6 +503,7 @@ pub struct Origin<'a> {
487503
pub(crate) path: Cow<'a, str>,
488504
pub(crate) line: Option<usize>,
489505
pub(crate) char_column: Option<usize>,
506+
pub(crate) url: Option<Cow<'a, str>>,
490507
}
491508

492509
impl<'a> Origin<'a> {
@@ -502,6 +519,7 @@ impl<'a> Origin<'a> {
502519
path: path.into(),
503520
line: None,
504521
char_column: None,
522+
url: None,
505523
}
506524
}
507525

@@ -522,6 +540,20 @@ impl<'a> Origin<'a> {
522540
self.char_column = Some(char_column);
523541
self
524542
}
543+
544+
/// The URL to the origin. Can be a `file://` URL.
545+
///
546+
/// <div class="warning">
547+
///
548+
/// Text passed to this function is considered "untrusted input", as such
549+
/// all text is passed through a normalization function. Pre-styled text is
550+
/// not allowed to be passed to this function.
551+
///
552+
/// </div>
553+
pub fn path_url(mut self, uri: impl Into<Cow<'a, str>>) -> Self {
554+
self.url = Some(uri.into());
555+
self
556+
}
525557
}
526558

527559
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)