Fix hover_popover.rs after bad rebase

This commit is contained in:
Julia 2023-10-09 14:28:53 -04:00
parent f18f870206
commit 7020050b06
3 changed files with 92 additions and 102 deletions

View file

@ -60,7 +60,6 @@ use itertools::Itertools;
pub use language::{char_kind, CharKind};
use language::{
language_settings::{self, all_language_settings, InlayHintSettings},
markdown::MarkdownHighlight,
point_from_lsp, AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion,
CursorShape, Diagnostic, DiagnosticSeverity, Documentation, File, IndentKind, IndentSize,
Language, LanguageServerName, OffsetRangeExt, OffsetUtf16, Point, Selection, SelectionGoal,
@ -139,45 +138,21 @@ pub fn render_parsed_markdown(
.highlights
.iter()
.filter_map(|(range, highlight)| {
let highlight = match highlight {
MarkdownHighlight::Style(style) => {
let mut highlight = HighlightStyle::default();
if style.italic {
highlight.italic = Some(true);
}
if style.underline {
highlight.underline = Some(fonts::Underline {
thickness: 1.0.into(),
..Default::default()
});
}
if style.weight != fonts::Weight::default() {
highlight.weight = Some(style.weight);
}
highlight
}
MarkdownHighlight::Code(id) => id.style(&editor_style.syntax)?,
};
let highlight = highlight.to_highlight_style(&editor_style.syntax)?;
Some((range.clone(), highlight))
})
.collect::<Vec<_>>(),
)
.with_custom_runs(parsed.region_ranges, move |ix, bounds, scene, _| {
.with_custom_runs(parsed.region_ranges, move |ix, bounds, cx| {
region_id += 1;
let region = parsed.regions[ix].clone();
if let Some(url) = region.link_url {
scene.push_cursor_region(CursorRegion {
cx.scene().push_cursor_region(CursorRegion {
bounds,
style: CursorStyle::PointingHand,
});
scene.push_mouse_region(
cx.scene().push_mouse_region(
MouseRegion::new::<RenderedMarkdown>(view_id, region_id, bounds)
.on_click::<Editor, _>(MouseButton::Left, move |_, _, cx| {
cx.platform().open_url(&url)
@ -186,7 +161,7 @@ pub fn render_parsed_markdown(
}
if region.code {
scene.push_quad(gpui::Quad {
cx.scene().push_quad(gpui::Quad {
bounds,
background: Some(code_span_background_color),
border: Default::default(),

View file

@ -1,6 +1,6 @@
use crate::{
display_map::{InlayOffset, ToDisplayPoint},
link_go_to_definition::{DocumentRange, InlayRange},
link_go_to_definition::{InlayHighlight, RangeInEditor},
Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSettings, EditorSnapshot, EditorStyle,
ExcerptId, RangeToAnchorExt,
};
@ -51,19 +51,18 @@ pub fn hover_at(editor: &mut Editor, point: Option<DisplayPoint>, cx: &mut ViewC
pub struct InlayHover {
pub excerpt: ExcerptId,
pub triggered_from: InlayOffset,
pub range: InlayRange,
pub range: InlayHighlight,
pub tooltip: HoverBlock,
}
pub fn find_hovered_hint_part(
label_parts: Vec<InlayHintLabelPart>,
hint_range: Range<InlayOffset>,
hint_start: InlayOffset,
hovered_offset: InlayOffset,
) -> Option<(InlayHintLabelPart, Range<InlayOffset>)> {
if hovered_offset >= hint_range.start && hovered_offset <= hint_range.end {
let mut hovered_character = (hovered_offset - hint_range.start).0;
let mut part_start = hint_range.start;
if hovered_offset >= hint_start {
let mut hovered_character = (hovered_offset - hint_start).0;
let mut part_start = hint_start;
for part in label_parts {
let part_len = part.value.chars().count();
if hovered_character > part_len {
@ -89,10 +88,8 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
};
if let Some(InfoPopover { symbol_range, .. }) = &editor.hover_state.info_popover {
if let DocumentRange::Inlay(range) = symbol_range {
if (range.highlight_start..range.highlight_end)
.contains(&inlay_hover.triggered_from)
{
if let RangeInEditor::Inlay(range) = symbol_range {
if range == &inlay_hover.range {
// Hover triggered from same location as last time. Don't show again.
return;
}
@ -100,18 +97,6 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
hide_hover(editor, cx);
}
let snapshot = editor.snapshot(cx);
// Don't request again if the location is the same as the previous request
if let Some(triggered_from) = editor.hover_state.triggered_from {
if inlay_hover.triggered_from
== snapshot
.display_snapshot
.anchor_to_inlay_offset(triggered_from)
{
return;
}
}
let task = cx.spawn(|this, mut cx| {
async move {
cx.background()
@ -127,7 +112,7 @@ pub fn hover_at_inlay(editor: &mut Editor, inlay_hover: InlayHover, cx: &mut Vie
let hover_popover = InfoPopover {
project: project.clone(),
symbol_range: DocumentRange::Inlay(inlay_hover.range),
symbol_range: RangeInEditor::Inlay(inlay_hover.range.clone()),
blocks,
parsed_content,
};
@ -331,7 +316,7 @@ fn show_hover(
Some(InfoPopover {
project: project.clone(),
symbol_range: DocumentRange::Text(range),
symbol_range: RangeInEditor::Text(range),
blocks,
parsed_content,
})
@ -449,8 +434,8 @@ impl HoverState {
self.info_popover
.as_ref()
.map(|info_popover| match &info_popover.symbol_range {
DocumentRange::Text(range) => &range.start,
DocumentRange::Inlay(range) => &range.inlay_position,
RangeInEditor::Text(range) => &range.start,
RangeInEditor::Inlay(range) => &range.inlay_position,
})
})?;
let point = anchor.to_display_point(&snapshot.display_snapshot);
@ -476,7 +461,7 @@ impl HoverState {
#[derive(Debug, Clone)]
pub struct InfoPopover {
pub project: ModelHandle<Project>,
symbol_range: DocumentRange,
symbol_range: RangeInEditor,
pub blocks: Vec<HoverBlock>,
parsed_content: ParsedMarkdown,
}
@ -587,14 +572,12 @@ mod tests {
inlay_hint_cache::tests::{cached_hint_labels, visible_hint_labels},
link_go_to_definition::update_inlay_link_and_hover_points,
test::editor_lsp_test_context::EditorLspTestContext,
InlayId,
};
use collections::BTreeSet;
use gpui::fonts::Weight;
use gpui::fonts::{HighlightStyle, Underline, Weight};
use indoc::indoc;
use language::{
language_settings::InlayHintSettings, markdown::MarkdownHighlightStyle, Diagnostic,
DiagnosticSet,
};
use language::{language_settings::InlayHintSettings, Diagnostic, DiagnosticSet};
use lsp::LanguageServerId;
use project::{HoverBlock, HoverBlockKind};
use smol::stream::StreamExt;
@ -896,17 +879,16 @@ mod tests {
#[gpui::test]
fn test_render_blocks(cx: &mut gpui::TestAppContext) {
use markdown::MarkdownHighlight;
init_test(cx, |_| {});
cx.add_window(|cx| {
let editor = Editor::single_line(None, cx);
let style = editor.style(cx);
struct Row {
blocks: Vec<HoverBlock>,
expected_marked_text: String,
expected_styles: Vec<MarkdownHighlight>,
expected_styles: Vec<HighlightStyle>,
}
let rows = &[
@ -917,10 +899,10 @@ mod tests {
kind: HoverBlockKind::Markdown,
}],
expected_marked_text: "one «two» three".to_string(),
expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
weight: Weight::BOLD,
expected_styles: vec![HighlightStyle {
weight: Some(Weight::BOLD),
..Default::default()
})],
}],
},
// Links
Row {
@ -929,10 +911,13 @@ mod tests {
kind: HoverBlockKind::Markdown,
}],
expected_marked_text: "one «two» three".to_string(),
expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
underline: true,
expected_styles: vec![HighlightStyle {
underline: Some(Underline {
thickness: 1.0.into(),
..Default::default()
}),
..Default::default()
})],
}],
},
// Lists
Row {
@ -957,10 +942,13 @@ mod tests {
- «c»
- d"
.unindent(),
expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
underline: true,
expected_styles: vec![HighlightStyle {
underline: Some(Underline {
thickness: 1.0.into(),
..Default::default()
}),
..Default::default()
})],
}],
},
// Multi-paragraph list items
Row {
@ -988,10 +976,13 @@ mod tests {
- ten
- six"
.unindent(),
expected_styles: vec![MarkdownHighlight::Style(MarkdownHighlightStyle {
underline: true,
expected_styles: vec![HighlightStyle {
underline: Some(Underline {
thickness: 1.0.into(),
..Default::default()
}),
..Default::default()
})],
}],
},
];
@ -1012,8 +1003,18 @@ mod tests {
rendered.text, expected_text,
"wrong text for input {blocks:?}"
);
let rendered_highlights: Vec<_> = rendered
.highlights
.iter()
.filter_map(|(range, highlight)| {
let highlight = highlight.to_highlight_style(&style.syntax)?;
Some((range.clone(), highlight))
})
.collect();
assert_eq!(
rendered.highlights, expected_highlights,
rendered_highlights, expected_highlights,
"wrong highlights for input {blocks:?}"
);
}
@ -1247,25 +1248,16 @@ mod tests {
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100));
cx.foreground().run_until_parked();
cx.update_editor(|editor, cx| {
let snapshot = editor.snapshot(cx);
let hover_state = &editor.hover_state;
assert!(hover_state.diagnostic_popover.is_none() && hover_state.info_popover.is_some());
let popover = hover_state.info_popover.as_ref().unwrap();
let buffer_snapshot = editor.buffer().update(cx, |buffer, cx| buffer.snapshot(cx));
let entire_inlay_start = snapshot.display_point_to_inlay_offset(
inlay_range.start.to_display_point(&snapshot),
Bias::Left,
);
let expected_new_type_label_start = InlayOffset(entire_inlay_start.0 + ": ".len());
assert_eq!(
popover.symbol_range,
DocumentRange::Inlay(InlayRange {
RangeInEditor::Inlay(InlayHighlight {
inlay: InlayId::Hint(0),
inlay_position: buffer_snapshot.anchor_at(inlay_range.start, Bias::Right),
highlight_start: expected_new_type_label_start,
highlight_end: InlayOffset(
expected_new_type_label_start.0 + new_type_label.len()
),
range: ": ".len()..": ".len() + new_type_label.len(),
}),
"Popover range should match the new type label part"
);
@ -1309,23 +1301,17 @@ mod tests {
.advance_clock(Duration::from_millis(HOVER_DELAY_MILLIS + 100));
cx.foreground().run_until_parked();
cx.update_editor(|editor, cx| {
let snapshot = editor.snapshot(cx);
let hover_state = &editor.hover_state;
assert!(hover_state.diagnostic_popover.is_none() && hover_state.info_popover.is_some());
let popover = hover_state.info_popover.as_ref().unwrap();
let buffer_snapshot = editor.buffer().update(cx, |buffer, cx| buffer.snapshot(cx));
let entire_inlay_start = snapshot.display_point_to_inlay_offset(
inlay_range.start.to_display_point(&snapshot),
Bias::Left,
);
let expected_struct_label_start =
InlayOffset(entire_inlay_start.0 + ": ".len() + new_type_label.len() + "<".len());
assert_eq!(
popover.symbol_range,
DocumentRange::Inlay(InlayRange {
RangeInEditor::Inlay(InlayHighlight {
inlay: InlayId::Hint(0),
inlay_position: buffer_snapshot.anchor_at(inlay_range.start, Bias::Right),
highlight_start: expected_struct_label_start,
highlight_end: InlayOffset(expected_struct_label_start.0 + struct_label.len()),
range: ": ".len() + new_type_label.len() + "<".len()
..": ".len() + new_type_label.len() + "<".len() + struct_label.len(),
}),
"Popover range should match the struct label part"
);

View file

@ -2,7 +2,7 @@ use std::ops::Range;
use std::sync::Arc;
use crate::{HighlightId, Language, LanguageRegistry};
use gpui::fonts::Weight;
use gpui::fonts::{self, HighlightStyle, Weight};
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag};
#[derive(Debug, Clone)]
@ -19,6 +19,35 @@ pub enum MarkdownHighlight {
Code(HighlightId),
}
impl MarkdownHighlight {
pub fn to_highlight_style(&self, theme: &theme::SyntaxTheme) -> Option<HighlightStyle> {
match self {
MarkdownHighlight::Style(style) => {
let mut highlight = HighlightStyle::default();
if style.italic {
highlight.italic = Some(true);
}
if style.underline {
highlight.underline = Some(fonts::Underline {
thickness: 1.0.into(),
..Default::default()
});
}
if style.weight != fonts::Weight::default() {
highlight.weight = Some(style.weight);
}
Some(highlight)
}
MarkdownHighlight::Code(id) => id.style(theme),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct MarkdownHighlightStyle {
pub italic: bool,