Show error code in diagnostic header

Antonio Scandurra created

Change summary

crates/diagnostics/src/diagnostics.rs | 32 +++++++++++++++++-----------
crates/editor/src/editor.rs           |  4 +++
crates/theme/src/theme.rs             |  5 ++++
crates/zed/assets/themes/_base.toml   |  1 
4 files changed, 29 insertions(+), 13 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -13,7 +13,7 @@ use gpui::{
     MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle,
 };
 use language::{
-    Bias, Buffer, DiagnosticEntry, DiagnosticSeverity, Point, Selection, SelectionGoal,
+    Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, SelectionGoal,
 };
 use postage::watch;
 use project::{Project, ProjectPath};
@@ -346,16 +346,16 @@ impl ProjectDiagnosticsEditor {
 
                             if is_first_excerpt_for_group {
                                 is_first_excerpt_for_group = false;
-                                let primary = &group.entries[group.primary_ix].diagnostic;
-                                let message =
+                                let mut primary =
+                                    group.entries[group.primary_ix].diagnostic.clone();
+                                primary.message =
                                     primary.message.split('\n').next().unwrap().to_string();
                                 group_state.block_count += 1;
                                 blocks_to_add.push(BlockProperties {
                                     position: header_position,
                                     height: 2,
                                     render: diagnostic_header_renderer(
-                                        message,
-                                        primary.severity,
+                                        primary,
                                         self.build_settings.clone(),
                                     ),
                                     disposition: BlockDisposition::Above,
@@ -694,8 +694,7 @@ fn path_header_renderer(buffer: ModelHandle<Buffer>, build_settings: BuildSettin
 }
 
 fn diagnostic_header_renderer(
-    message: String,
-    severity: DiagnosticSeverity,
+    diagnostic: Diagnostic,
     build_settings: BuildSettings,
 ) -> RenderBlock {
     enum Run {
@@ -706,7 +705,7 @@ fn diagnostic_header_renderer(
     let mut prev_ix = 0;
     let mut inside_block = false;
     let mut runs = Vec::new();
-    for (backtick_ix, _) in message.match_indices('`') {
+    for (backtick_ix, _) in diagnostic.message.match_indices('`') {
         if backtick_ix > prev_ix {
             if inside_block {
                 runs.push(Run::Code(prev_ix..backtick_ix));
@@ -718,18 +717,18 @@ fn diagnostic_header_renderer(
         inside_block = !inside_block;
         prev_ix = backtick_ix + 1;
     }
-    if prev_ix < message.len() {
+    if prev_ix < diagnostic.message.len() {
         if inside_block {
-            runs.push(Run::Code(prev_ix..message.len()));
+            runs.push(Run::Code(prev_ix..diagnostic.message.len()));
         } else {
-            runs.push(Run::Text(prev_ix..message.len()));
+            runs.push(Run::Text(prev_ix..diagnostic.message.len()));
         }
     }
 
     Arc::new(move |cx| {
         let settings = build_settings(cx);
         let style = &settings.style.diagnostic_header;
-        let icon = if severity == DiagnosticSeverity::ERROR {
+        let icon = if diagnostic.severity == DiagnosticSeverity::ERROR {
             Svg::new("icons/diagnostic-error-10.svg")
                 .with_color(settings.style.error_diagnostic.text)
         } else {
@@ -762,12 +761,19 @@ fn diagnostic_header_renderer(
                         range = run_range.clone();
                     }
                 }
-                Label::new(message[range].to_string(), text_style)
+                Label::new(diagnostic.message[range].to_string(), text_style)
                     .contained()
                     .with_style(container_style)
                     .aligned()
                     .boxed()
             }))
+            .with_children(diagnostic.code.clone().map(|code| {
+                Label::new(code, style.code.text.clone())
+                    .contained()
+                    .with_style(style.code.container)
+                    .aligned()
+                    .boxed()
+            }))
             .contained()
             .with_style(style.container)
             .with_padding_left(cx.line_number_x)

crates/editor/src/editor.rs 🔗

@@ -3853,6 +3853,10 @@ impl EditorSettings {
                             container: Default::default(),
                             text: text.clone(),
                         },
+                        code: theme::ContainedText {
+                            container: Default::default(),
+                            text: text.clone(),
+                        },
                         icon: Default::default(),
                     },
                     error_diagnostic: Default::default(),

crates/theme/src/theme.rs 🔗

@@ -277,6 +277,7 @@ pub struct DiagnosticHeader {
     pub container: ContainerStyle,
     pub text: TextStyle,
     pub highlighted_text: ContainedText,
+    pub code: ContainedText,
     pub icon: DiagnosticHeaderIcon,
 }
 
@@ -360,6 +361,10 @@ impl InputEditorStyle {
                     container: Default::default(),
                     text: self.text.clone(),
                 },
+                code: ContainedText {
+                    container: Default::default(),
+                    text: self.text.clone(),
+                },
                 icon: Default::default(),
             },
             error_diagnostic: Default::default(),

crates/zed/assets/themes/_base.toml 🔗

@@ -264,6 +264,7 @@ path = { extends = "$text.2", size = 14, margin.left = 12 }
 background = "$state.active_line"
 border = { width = 1, top = true, bottom = true, color = "$border.0" }
 text = { extends = "$text.1", size = 14 }
+code = { extends = "$text.2", size = 14, margin.left = 10 }
 icon = { width = 10, margin.right = 8 }
 
 [editor.diagnostic_header.highlighted_text]