Improve terminal hover tooltips (#26487)

Follow-up of https://github.com/zed-industries/zed/pull/26174

* Fixes `./path/foo.bar` not properly parsed as valid open target
* Shows full open target's path in cmd-hover tooltips

Before:

<img width="864" alt="before_1"
src="https://github.com/user-attachments/assets/2575b887-6c4d-486e-8e92-dd76aedf8103"
/>
<img width="864" alt="before_2"
src="https://github.com/user-attachments/assets/ded1f203-523c-4b75-afe9-fe541c785798"
/>

After:

<img width="864" alt="after_1"
src="https://github.com/user-attachments/assets/c50d9ba3-5dfb-4cfb-aed6-00e6fa6f088e"
/>
<img width="864" alt="after_2"
src="https://github.com/user-attachments/assets/0cdc8f34-7faa-4aab-87f3-dc0c8b499842"
/>

Release Notes:



- N/A
This commit is contained in:
Kirill Bulatov 2025-03-12 00:17:12 +02:00 committed by GitHub
parent 04961a0186
commit 8d6abf6537
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 79 additions and 53 deletions

View file

@ -21,7 +21,7 @@ use terminal::{
},
},
terminal_settings::TerminalSettings,
HoveredWord, IndexedCell, Terminal, TerminalBounds, TerminalContent,
IndexedCell, Terminal, TerminalBounds, TerminalContent,
};
use theme::{ActiveTheme, Theme, ThemeSettings};
use ui::{ParentElement, Tooltip};
@ -45,7 +45,6 @@ pub struct LayoutState {
display_offset: usize,
hyperlink_tooltip: Option<AnyElement>,
gutter: Pixels,
last_hovered_word: Option<HoveredWord>,
block_below_cursor_element: Option<AnyElement>,
}
@ -157,7 +156,6 @@ pub struct TerminalElement {
focus: FocusHandle,
focused: bool,
cursor_visible: bool,
can_navigate_to_selected_word: bool,
interactivity: Interactivity,
block_below_cursor: Option<Rc<BlockProperties>>,
}
@ -178,7 +176,6 @@ impl TerminalElement {
focus: FocusHandle,
focused: bool,
cursor_visible: bool,
can_navigate_to_selected_word: bool,
block_below_cursor: Option<Rc<BlockProperties>>,
) -> TerminalElement {
TerminalElement {
@ -188,7 +185,6 @@ impl TerminalElement {
focused,
focus: focus.clone(),
cursor_visible,
can_navigate_to_selected_word,
block_below_cursor,
interactivity: Default::default(),
}
@ -695,27 +691,29 @@ impl Element for TerminalElement {
let background_color = theme.colors().terminal_background;
let last_hovered_word = self.terminal.update(cx, |terminal, cx| {
let (last_hovered_word, hover_target) = self.terminal.update(cx, |terminal, cx| {
terminal.set_size(dimensions);
terminal.sync(window, cx);
if self.can_navigate_to_selected_word
&& window.modifiers().secondary()
if window.modifiers().secondary()
&& bounds.contains(&window.mouse_position())
&& self.terminal_view.read(cx).hover_target_tooltip.is_some()
{
terminal.last_content.last_hovered_word.clone()
let hover_target = self.terminal_view.read(cx).hover_target_tooltip.clone();
let last_hovered_word = terminal.last_content.last_hovered_word.clone();
(last_hovered_word, hover_target)
} else {
None
(None, None)
}
});
let scroll_top = self.terminal_view.read(cx).scroll_top;
let hyperlink_tooltip = last_hovered_word.clone().map(|hovered_word| {
let hyperlink_tooltip = hover_target.as_ref().map(|hover_target| {
let offset = bounds.origin + point(gutter, px(0.)) - point(px(0.), scroll_top);
let mut element = div()
.size_full()
.id("terminal-element")
.tooltip(Tooltip::text(hovered_word.word.clone()))
.tooltip(Tooltip::text(hover_target.clone()))
.into_any_element();
element.prepaint_as_root(offset, bounds.size.into(), window, cx);
element
@ -851,7 +849,6 @@ impl Element for TerminalElement {
display_offset,
hyperlink_tooltip,
gutter,
last_hovered_word,
block_below_cursor_element,
}
},
@ -884,7 +881,10 @@ impl Element for TerminalElement {
};
self.register_mouse_listeners(layout.mode, &layout.hitbox, window);
if self.can_navigate_to_selected_word && layout.last_hovered_word.is_some() {
if window.modifiers().secondary()
&& bounds.contains(&window.mouse_position())
&& self.terminal_view.read(cx).hover_target_tooltip.is_some()
{
window.set_cursor_style(gpui::CursorStyle::PointingHand, &layout.hitbox);
} else {
window.set_cursor_style(gpui::CursorStyle::IBeam, &layout.hitbox);