markdown preview: Add link tooltips (#10161)
Adds tooltips to the markdown preview, similar to how its done for `RichText` https://github.com/zed-industries/zed/assets/53836821/523519d4-e392-46ef-9fe0-6692871b317d Release Notes: - Added tooltips when hovering over links inside the markdown preview
This commit is contained in:
parent
dde87f6468
commit
5d88d9c0d7
2 changed files with 39 additions and 6 deletions
|
@ -2,7 +2,7 @@ use gpui::{
|
||||||
px, FontStyle, FontWeight, HighlightStyle, SharedString, StrikethroughStyle, UnderlineStyle,
|
px, FontStyle, FontWeight, HighlightStyle, SharedString, StrikethroughStyle, UnderlineStyle,
|
||||||
};
|
};
|
||||||
use language::HighlightId;
|
use language::HighlightId;
|
||||||
use std::{ops::Range, path::PathBuf};
|
use std::{fmt::Display, ops::Range, path::PathBuf};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
|
@ -226,7 +226,9 @@ pub enum Link {
|
||||||
},
|
},
|
||||||
/// A link to a path on the filesystem.
|
/// A link to a path on the filesystem.
|
||||||
Path {
|
Path {
|
||||||
/// The path to the item.
|
/// The path as provided in the Markdown document.
|
||||||
|
display_path: PathBuf,
|
||||||
|
/// The absolute path to the item.
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -239,16 +241,32 @@ impl Link {
|
||||||
|
|
||||||
let path = PathBuf::from(&text);
|
let path = PathBuf::from(&text);
|
||||||
if path.is_absolute() && path.exists() {
|
if path.is_absolute() && path.exists() {
|
||||||
return Some(Link::Path { path });
|
return Some(Link::Path {
|
||||||
|
display_path: path.clone(),
|
||||||
|
path,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(file_location_directory) = file_location_directory {
|
if let Some(file_location_directory) = file_location_directory {
|
||||||
|
let display_path = path;
|
||||||
let path = file_location_directory.join(text);
|
let path = file_location_directory.join(text);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
return Some(Link::Path { path });
|
return Some(Link::Path { display_path, path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Link {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Link::Web { url } => write!(f, "{}", url),
|
||||||
|
Link::Path {
|
||||||
|
display_path,
|
||||||
|
path: _,
|
||||||
|
} => write!(f, "{}", display_path.display()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use theme::{ActiveTheme, SyntaxTheme};
|
use theme::{ActiveTheme, SyntaxTheme};
|
||||||
use ui::{h_flex, v_flex, Checkbox, Selection};
|
use ui::{h_flex, v_flex, Checkbox, LinkPreview, Selection};
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
pub struct RenderContext {
|
pub struct RenderContext {
|
||||||
|
@ -328,11 +328,26 @@ fn render_markdown_text(parsed: &ParsedMarkdownText, cx: &mut RenderContext) ->
|
||||||
element_id,
|
element_id,
|
||||||
StyledText::new(parsed.contents.clone()).with_highlights(&cx.text_style, highlights),
|
StyledText::new(parsed.contents.clone()).with_highlights(&cx.text_style, highlights),
|
||||||
)
|
)
|
||||||
|
.tooltip({
|
||||||
|
let links = links.clone();
|
||||||
|
let link_ranges = link_ranges.clone();
|
||||||
|
move |idx, cx| {
|
||||||
|
for (ix, range) in link_ranges.iter().enumerate() {
|
||||||
|
if range.contains(&idx) {
|
||||||
|
return Some(LinkPreview::new(&links[ix].to_string(), cx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
.on_click(
|
.on_click(
|
||||||
link_ranges,
|
link_ranges,
|
||||||
move |clicked_range_ix, window_cx| match &links[clicked_range_ix] {
|
move |clicked_range_ix, window_cx| match &links[clicked_range_ix] {
|
||||||
Link::Web { url } => window_cx.open_url(url),
|
Link::Web { url } => window_cx.open_url(url),
|
||||||
Link::Path { path } => {
|
Link::Path {
|
||||||
|
path,
|
||||||
|
display_path: _,
|
||||||
|
} => {
|
||||||
if let Some(workspace) = &workspace {
|
if let Some(workspace) = &workspace {
|
||||||
_ = workspace.update(window_cx, |workspace, cx| {
|
_ = workspace.update(window_cx, |workspace, cx| {
|
||||||
workspace.open_abs_path(path.clone(), false, cx).detach();
|
workspace.open_abs_path(path.clone(), false, cx).detach();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue