@@ -11,11 +11,11 @@ use gpui::{
StyleRefinement, Styled, Task, TextStyleRefinement, View, ViewContext,
};
use itertools::Itertools;
-use language::{Diagnostic, DiagnosticEntry, Language, LanguageRegistry};
+use language::{DiagnosticEntry, Language, LanguageRegistry};
use lsp::DiagnosticSeverity;
use markdown::{Markdown, MarkdownStyle};
use multi_buffer::ToOffset;
-use project::{HoverBlock, InlayHintLabelPart};
+use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart};
use settings::Settings;
use std::rc::Rc;
use std::{borrow::Cow, cell::RefCell};
@@ -263,50 +263,14 @@ fn show_hover(
delay.await;
}
- let local_diagnostic = if let Some(invisible) = snapshot
+ let local_diagnostic = snapshot
.buffer_snapshot
- .chars_at(anchor)
- .next()
- .filter(|&c| is_invisible(c))
- {
- let after = snapshot.buffer_snapshot.anchor_after(
- anchor.to_offset(&snapshot.buffer_snapshot) + invisible.len_utf8(),
- );
- Some(DiagnosticEntry {
- diagnostic: Diagnostic {
- severity: DiagnosticSeverity::HINT,
- message: format!("Unicode character U+{:02X}", invisible as u32),
- ..Default::default()
- },
- range: anchor..after,
- })
- } else if let Some(invisible) = snapshot
- .buffer_snapshot
- .reversed_chars_at(anchor)
- .next()
- .filter(|&c| is_invisible(c))
- {
- let before = snapshot.buffer_snapshot.anchor_before(
- anchor.to_offset(&snapshot.buffer_snapshot) - invisible.len_utf8(),
- );
- Some(DiagnosticEntry {
- diagnostic: Diagnostic {
- severity: DiagnosticSeverity::HINT,
- message: format!("Unicode character U+{:02X}", invisible as u32),
- ..Default::default()
- },
- range: before..anchor,
- })
- } else {
- snapshot
- .buffer_snapshot
- .diagnostics_in_range(anchor..anchor, false)
- // Find the entry with the most specific range
- .min_by_key(|entry| {
- let range = entry.range.to_offset(&snapshot.buffer_snapshot);
- range.end - range.start
- })
- };
+ .diagnostics_in_range(anchor..anchor, false)
+ // Find the entry with the most specific range
+ .min_by_key(|entry| {
+ let range = entry.range.to_offset(&snapshot.buffer_snapshot);
+ range.end - range.start
+ });
let diagnostic_popover = if let Some(local_diagnostic) = local_diagnostic {
let text = match local_diagnostic.diagnostic.source {
@@ -389,6 +353,31 @@ fn show_hover(
this.hover_state.diagnostic_popover = diagnostic_popover;
})?;
+ let invisible_char = if let Some(invisible) = snapshot
+ .buffer_snapshot
+ .chars_at(anchor)
+ .next()
+ .filter(|&c| is_invisible(c))
+ {
+ let after = snapshot.buffer_snapshot.anchor_after(
+ anchor.to_offset(&snapshot.buffer_snapshot) + invisible.len_utf8(),
+ );
+ Some((invisible, anchor..after))
+ } else if let Some(invisible) = snapshot
+ .buffer_snapshot
+ .reversed_chars_at(anchor)
+ .next()
+ .filter(|&c| is_invisible(c))
+ {
+ let before = snapshot.buffer_snapshot.anchor_before(
+ anchor.to_offset(&snapshot.buffer_snapshot) - invisible.len_utf8(),
+ );
+
+ Some((invisible, before..anchor))
+ } else {
+ None
+ };
+
let hovers_response = if let Some(hover_request) = hover_request {
hover_request.await
} else {
@@ -396,8 +385,26 @@ fn show_hover(
};
let snapshot = this.update(&mut cx, |this, cx| this.snapshot(cx))?;
let mut hover_highlights = Vec::with_capacity(hovers_response.len());
- let mut info_popovers = Vec::with_capacity(hovers_response.len());
- let mut info_popover_tasks = Vec::with_capacity(hovers_response.len());
+ let mut info_popovers = Vec::with_capacity(
+ hovers_response.len() + if invisible_char.is_some() { 1 } else { 0 },
+ );
+
+ if let Some((invisible, range)) = invisible_char {
+ let blocks = vec![HoverBlock {
+ text: format!("Unicode character U+{:02X}", invisible as u32),
+ kind: HoverBlockKind::PlainText,
+ }];
+ let parsed_content = parse_blocks(&blocks, &language_registry, None, &mut cx).await;
+ let scroll_handle = ScrollHandle::new();
+ info_popovers.push(InfoPopover {
+ symbol_range: RangeInEditor::Text(range),
+ parsed_content,
+ scrollbar_state: ScrollbarState::new(scroll_handle.clone()),
+ scroll_handle,
+ keyboard_grace: Rc::new(RefCell::new(ignore_timeout)),
+ anchor: Some(anchor),
+ })
+ }
for hover_result in hovers_response {
// Create symbol range of anchors for highlighting and filtering of future requests.
@@ -410,7 +417,6 @@ fn show_hover(
let end = snapshot
.buffer_snapshot
.anchor_in_excerpt(excerpt_id, range.end)?;
-
Some(start..end)
})
.or_else(|| {
@@ -428,21 +434,15 @@ fn show_hover(
let parsed_content =
parse_blocks(&blocks, &language_registry, language, &mut cx).await;
let scroll_handle = ScrollHandle::new();
- info_popover_tasks.push((
- range.clone(),
- InfoPopover {
- symbol_range: RangeInEditor::Text(range),
- parsed_content,
- scrollbar_state: ScrollbarState::new(scroll_handle.clone()),
- scroll_handle,
- keyboard_grace: Rc::new(RefCell::new(ignore_timeout)),
- anchor: Some(anchor),
- },
- ));
- }
- for (highlight_range, info_popover) in info_popover_tasks {
- hover_highlights.push(highlight_range);
- info_popovers.push(info_popover);
+ hover_highlights.push(range.clone());
+ info_popovers.push(InfoPopover {
+ symbol_range: RangeInEditor::Text(range),
+ parsed_content,
+ scrollbar_state: ScrollbarState::new(scroll_handle.clone()),
+ scroll_handle,
+ keyboard_grace: Rc::new(RefCell::new(ignore_timeout)),
+ anchor: Some(anchor),
+ });
}
this.update(&mut cx, |editor, cx| {
@@ -732,6 +732,7 @@ impl InfoPopover {
cx.notify();
self.scroll_handle.set_offset(current);
}
+
fn render_vertical_scrollbar(&self, cx: &mut ViewContext<Editor>) -> Stateful<Div> {
div()
.occlude()