Compare commits

...

3 Commits

Author SHA1 Message Date
Richard Feldman
0ff95fec62 Add a tooltip to the icon for the language name 2025-05-01 10:58:41 -04:00
Richard Feldman
845cf799c6 Only show icons, not language names, above code blocks 2025-05-01 10:58:41 -04:00
Richard Feldman
22c1090163 Respect cursor_pointer when ButtonLike is disabled 2025-05-01 10:57:44 -04:00
2 changed files with 69 additions and 34 deletions

View File

@@ -21,9 +21,9 @@ use editor::scroll::Autoscroll;
use editor::{Editor, EditorElement, EditorEvent, EditorStyle, MultiBuffer}; use editor::{Editor, EditorElement, EditorEvent, EditorStyle, MultiBuffer};
use gpui::{ use gpui::{
AbsoluteLength, Animation, AnimationExt, AnyElement, App, ClickEvent, ClipboardEntry, AbsoluteLength, Animation, AnimationExt, AnyElement, App, ClickEvent, ClipboardEntry,
ClipboardItem, DefiniteLength, EdgesRefinement, Empty, Entity, EventEmitter, Focusable, Hsla, ClipboardItem, CursorStyle, DefiniteLength, EdgesRefinement, Empty, Entity, EventEmitter,
ListAlignment, ListState, MouseButton, PlatformDisplay, ScrollHandle, Stateful, Focusable, Hsla, ListAlignment, ListState, MouseButton, PlatformDisplay, ScrollHandle,
StyleRefinement, Subscription, Task, TextStyle, TextStyleRefinement, Transformation, Stateful, StyleRefinement, Subscription, Task, TextStyle, TextStyleRefinement, Transformation,
UnderlineStyle, WeakEntity, WindowHandle, linear_color_stop, linear_gradient, list, percentage, UnderlineStyle, WeakEntity, WindowHandle, linear_color_stop, linear_gradient, list, percentage,
pulsating_between, pulsating_between,
}; };
@@ -45,8 +45,8 @@ use std::time::Duration;
use text::ToPoint; use text::ToPoint;
use theme::ThemeSettings; use theme::ThemeSettings;
use ui::{ use ui::{
Disclosure, IconButton, KeyBinding, PopoverMenuHandle, Scrollbar, ScrollbarState, TextSize, ButtonLike, Disclosure, IconButton, KeyBinding, PopoverMenuHandle, Scrollbar, ScrollbarState,
Tooltip, prelude::*, TextSize, Tooltip, prelude::*,
}; };
use util::ResultExt as _; use util::ResultExt as _;
use util::markdown::MarkdownCodeBlock; use util::markdown::MarkdownCodeBlock;
@@ -360,25 +360,42 @@ fn render_markdown_code_block(
cx, cx,
)), )),
CodeBlockKind::FencedSrc(path_range) => path_range.path.file_name().map(|file_name| { CodeBlockKind::FencedSrc(path_range) => path_range.path.file_name().map(|file_name| {
let language = parsed_markdown
.languages_by_path
.get(&path_range.path)
.or_else(|| {
path_range
.path
.extension()
.and_then(OsStr::to_str)
.and_then(|str| {
let ext = SharedString::new(str.to_string());
parsed_markdown.languages_by_name.get(&ext)
})
});
// We tell the model to use /dev/null for the path instead of using ```language // We tell the model to use /dev/null for the path instead of using ```language
// because otherwise it consistently fails to use code citations. // because otherwise it consistently fails to use code citations.
if path_range.path.starts_with("/dev/null") { if path_range.path.starts_with("/dev/null") {
let ext = path_range let icon = language.and_then(|language| {
.path language
.extension() .config()
.and_then(OsStr::to_str) .matcher
.map(|str| SharedString::new(str.to_string())) .path_suffixes
.unwrap_or_default(); .iter()
.find_map(|extension| {
file_icons::FileIcons::get_icon(Path::new(extension), cx)
})
.map(|icon_path| {
code_block_icon(ix, icon_path, Some(language.name().into()))
})
});
render_code_language( div().children(icon).into_any_element()
parsed_markdown
.languages_by_path
.get(&path_range.path)
.or_else(|| parsed_markdown.languages_by_name.get(&ext)),
ext,
cx,
)
} else { } else {
let icon = file_icons::FileIcons::get_icon(&path_range.path, cx).map(|icon_path| {
code_block_icon(ix, icon_path, language.map(|lang| lang.name().into()))
});
let content = if let Some(parent) = path_range.path.parent() { let content = if let Some(parent) = path_range.path.parent() {
h_flex() h_flex()
.ml_1() .ml_1()
@@ -411,19 +428,11 @@ fn render_markdown_code_block(
.hover(|item| item.bg(cx.theme().colors().element_hover.opacity(0.5))) .hover(|item| item.bg(cx.theme().colors().element_hover.opacity(0.5)))
.tooltip(Tooltip::text("Jump to File")) .tooltip(Tooltip::text("Jump to File"))
.child( .child(
h_flex() h_flex().gap_0p5().children(icon).child(content).child(
.gap_0p5() Icon::new(IconName::ArrowUpRight)
.children( .size(IconSize::XSmall)
file_icons::FileIcons::get_icon(&path_range.path, cx) .color(Color::Ignored),
.map(Icon::from_path) ),
.map(|icon| icon.color(Color::Muted).size(IconSize::XSmall)),
)
.child(content)
.child(
Icon::new(IconName::ArrowUpRight)
.size(IconSize::XSmall)
.color(Color::Ignored),
),
) )
.on_click({ .on_click({
let path_range = path_range.clone(); let path_range = path_range.clone();
@@ -612,6 +621,26 @@ fn render_markdown_code_block(
) )
} }
fn code_block_icon(
ix: usize,
icon_path: SharedString,
tooltip: Option<SharedString>,
) -> ButtonLike {
let without_tooltip = ButtonLike::new(("code_block_icon", ix))
.disabled(true)
.cursor_style(CursorStyle::Arrow)
.child(
Icon::from_path(icon_path)
.color(Color::Muted)
.size(IconSize::XSmall),
);
match tooltip {
Some(tooltip) => without_tooltip.tooltip(Tooltip::text(tooltip)),
None => without_tooltip,
}
}
fn render_code_language( fn render_code_language(
language: Option<&Arc<Language>>, language: Option<&Arc<Language>>,
name_fallback: SharedString, name_fallback: SharedString,

View File

@@ -535,9 +535,15 @@ impl RenderOnce for ButtonLike {
ButtonSize::None => this, ButtonSize::None => this,
}) })
.bg(style.enabled(self.layer, cx).background) .bg(style.enabled(self.layer, cx).background)
.when(self.disabled, |this| this.cursor_not_allowed()) .when(self.disabled, |this| {
if self.cursor_style == CursorStyle::PointingHand {
this.cursor_not_allowed()
} else {
this.cursor(self.cursor_style)
}
})
.when(!self.disabled, |this| { .when(!self.disabled, |this| {
this.cursor_pointer() this.cursor(self.cursor_style)
.hover(|hover| hover.bg(style.hovered(self.layer, cx).background)) .hover(|hover| hover.bg(style.hovered(self.layer, cx).background))
.active(|active| active.bg(style.active(cx).background)) .active(|active| active.bg(style.active(cx).background))
}) })