Merge pull request #2432 from zed-industries/more-diagnostic-source

Julia created

Show diagnostic source in more places

Change summary

crates/diagnostics/src/diagnostics.rs | 15 ++++++++++++---
crates/editor/src/editor.rs           | 19 +++++++++++++++----
crates/theme/src/theme.rs             |  1 +
styles/src/styleTree/editor.ts        |  3 +++
4 files changed, 31 insertions(+), 7 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -677,7 +677,7 @@ impl Item for ProjectDiagnosticsEditor {
 }
 
 fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
-    let (message, highlights) = highlight_diagnostic_message(&diagnostic.message);
+    let (message, highlights) = highlight_diagnostic_message(Vec::new(), &diagnostic.message);
     Arc::new(move |cx| {
         let settings = cx.global::<Settings>();
         let theme = &settings.theme.editor;
@@ -697,8 +697,18 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
                 icon.constrained()
                     .with_width(icon_width)
                     .aligned()
-                    .contained(),
+                    .contained()
+                    .with_margin_right(cx.gutter_padding),
             )
+            .with_children(diagnostic.source.as_ref().map(|source| {
+                Label::new(
+                    format!("{source}: "),
+                    style.source.label.clone().with_font_size(font_size),
+                )
+                .contained()
+                .with_style(style.message.container)
+                .aligned()
+            }))
             .with_child(
                 Label::new(
                     message.clone(),
@@ -707,7 +717,6 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
                 .with_highlights(highlights.clone())
                 .contained()
                 .with_style(style.message.container)
-                .with_margin_left(cx.gutter_padding)
                 .aligned(),
             )
             .with_children(diagnostic.code.clone().map(|code| {

crates/editor/src/editor.rs 🔗

@@ -7509,8 +7509,16 @@ impl Deref for EditorStyle {
 
 pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> RenderBlock {
     let mut highlighted_lines = Vec::new();
-    for line in diagnostic.message.lines() {
-        highlighted_lines.push(highlight_diagnostic_message(line));
+    for (index, line) in diagnostic.message.lines().enumerate() {
+        let line = match &diagnostic.source {
+            Some(source) if index == 0 => {
+                let source_highlight = Vec::from_iter(0..source.len());
+                highlight_diagnostic_message(source_highlight, &format!("{source}: {line}"))
+            }
+
+            _ => highlight_diagnostic_message(Vec::new(), line),
+        };
+        highlighted_lines.push(line);
     }
 
     Arc::new(move |cx: &mut BlockContext| {
@@ -7534,11 +7542,14 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
     })
 }
 
-pub fn highlight_diagnostic_message(message: &str) -> (String, Vec<usize>) {
+pub fn highlight_diagnostic_message(
+    inital_highlights: Vec<usize>,
+    message: &str,
+) -> (String, Vec<usize>) {
     let mut message_without_backticks = String::new();
     let mut prev_offset = 0;
     let mut inside_block = false;
-    let mut highlights = Vec::new();
+    let mut highlights = inital_highlights;
     for (match_ix, (offset, _)) in message
         .match_indices('`')
         .chain([(message.len(), "")])

crates/theme/src/theme.rs 🔗

@@ -659,6 +659,7 @@ pub struct DiagnosticPathHeader {
 pub struct DiagnosticHeader {
     #[serde(flatten)]
     pub container: ContainerStyle,
+    pub source: ContainedLabel,
     pub message: ContainedLabel,
     pub code: ContainedText,
     pub text_scale_factor: f32,

styles/src/styleTree/editor.ts 🔗

@@ -176,6 +176,9 @@ export default function editor(colorScheme: ColorScheme) {
                     left: 10,
                 },
             },
+            source: {
+                text: text(colorScheme.middle, "sans", { size: "sm", weight: "bold", }),
+            },
             message: {
                 highlightText: text(colorScheme.middle, "sans", {
                     size: "sm",