Allow styling of invalid diagnostics

Antonio Scandurra and Nathan Sobo created

Co-Authored-By: Nathan Sobo <nathan@zed.dev>

Change summary

crates/editor/src/display_map/block_map.rs |  2 
crates/editor/src/element.rs               |  2 
crates/editor/src/lib.rs                   | 36 ++++++++++++++++--------
crates/lsp/src/lib.rs                      |  1 
crates/theme/src/lib.rs                    | 26 ++++++++++------
crates/zed/assets/themes/_base.toml        | 14 ++++++---
6 files changed, 52 insertions(+), 29 deletions(-)

Detailed changes

crates/editor/src/display_map/block_map.rs 🔗

@@ -394,7 +394,7 @@ impl<'a> BlockMapWriter<'a> {
             let id = BlockId(self.0.next_block_id.fetch_add(1, SeqCst));
             ids.push(id);
 
-            let position = buffer.anchor_before(block.position);
+            let position = buffer.anchor_after(block.position);
             let point = position.to_point(buffer);
             let start_row = wrap_snapshot
                 .from_point(Point::new(point.row, 0), Bias::Left)

crates/editor/src/element.rs 🔗

@@ -613,7 +613,7 @@ impl EditorElement {
                     }
 
                     let underline = if let Some(severity) = chunk.diagnostic {
-                        Some(super::diagnostic_style(severity, style).text)
+                        Some(super::diagnostic_style(severity, false, style).text)
                     } else {
                         highlight_style.underline
                     };

crates/editor/src/lib.rs 🔗

@@ -2284,7 +2284,7 @@ impl Editor {
                                             let settings = build_settings.borrow()(cx);
                                             vec![(
                                                 message_len,
-                                                diagnostic_style(severity, &settings.style)
+                                                diagnostic_style(severity, false, &settings.style)
                                                     .text
                                                     .into(),
                                             )]
@@ -2294,7 +2294,7 @@ impl Editor {
                                         let build_settings = build_settings.clone();
                                         move |cx| {
                                             let settings = build_settings.borrow()(cx);
-                                            diagnostic_style(severity, &settings.style).block
+                                            diagnostic_style(severity, false, &settings.style).block
                                         }
                                     })),
                                     disposition: BlockDisposition::Below,
@@ -2919,10 +2919,14 @@ impl EditorSettings {
                     selection: Default::default(),
                     guest_selections: Default::default(),
                     syntax: Default::default(),
-                    diagnostic_error: Default::default(),
-                    diagnostic_warning: Default::default(),
-                    diagnostic_information: Default::default(),
-                    diagnostic_hint: Default::default(),
+                    error_diagnostic: Default::default(),
+                    invalid_error_diagnostic: Default::default(),
+                    warning_diagnostic: Default::default(),
+                    invalid_warning_diagnostic: Default::default(),
+                    information_diagnostic: Default::default(),
+                    invalid_information_diagnostic: Default::default(),
+                    hint_diagnostic: Default::default(),
+                    invalid_hint_diagnostic: Default::default(),
                 }
             },
         }
@@ -3046,12 +3050,20 @@ impl SelectionExt for Selection<Point> {
     }
 }
 
-pub fn diagnostic_style(severity: DiagnosticSeverity, style: &EditorStyle) -> DiagnosticStyle {
-    match severity {
-        DiagnosticSeverity::ERROR => style.diagnostic_error,
-        DiagnosticSeverity::WARNING => style.diagnostic_warning,
-        DiagnosticSeverity::INFORMATION => style.diagnostic_information,
-        DiagnosticSeverity::HINT => style.diagnostic_hint,
+pub fn diagnostic_style(
+    severity: DiagnosticSeverity,
+    valid: bool,
+    style: &EditorStyle,
+) -> DiagnosticStyle {
+    match (severity, valid) {
+        (DiagnosticSeverity::ERROR, true) => style.error_diagnostic,
+        (DiagnosticSeverity::ERROR, false) => style.invalid_error_diagnostic,
+        (DiagnosticSeverity::WARNING, true) => style.warning_diagnostic,
+        (DiagnosticSeverity::WARNING, false) => style.invalid_warning_diagnostic,
+        (DiagnosticSeverity::INFORMATION, true) => style.information_diagnostic,
+        (DiagnosticSeverity::INFORMATION, false) => style.invalid_information_diagnostic,
+        (DiagnosticSeverity::HINT, true) => style.hint_diagnostic,
+        (DiagnosticSeverity::HINT, false) => style.invalid_hint_diagnostic,
         _ => Default::default(),
     }
 }

crates/lsp/src/lib.rs 🔗

@@ -136,6 +136,7 @@ impl LanguageServer {
                         buffer.resize(message_len, 0);
                         stdout.read_exact(&mut buffer).await?;
 
+                        println!("{}", std::str::from_utf8(&buffer).unwrap());
                         if let Ok(AnyNotification { method, params }) =
                             serde_json::from_slice(&buffer)
                         {

crates/theme/src/lib.rs 🔗

@@ -227,12 +227,14 @@ pub struct EditorStyle {
     pub line_number_active: Color,
     pub guest_selections: Vec<SelectionStyle>,
     pub syntax: Arc<SyntaxTheme>,
-    pub diagnostic_error: DiagnosticStyle,
-    pub diagnostic_warning: DiagnosticStyle,
-    #[serde(default)]
-    pub diagnostic_information: DiagnosticStyle,
-    #[serde(default)]
-    pub diagnostic_hint: DiagnosticStyle,
+    pub error_diagnostic: DiagnosticStyle,
+    pub invalid_error_diagnostic: DiagnosticStyle,
+    pub warning_diagnostic: DiagnosticStyle,
+    pub invalid_warning_diagnostic: DiagnosticStyle,
+    pub information_diagnostic: DiagnosticStyle,
+    pub invalid_information_diagnostic: DiagnosticStyle,
+    pub hint_diagnostic: DiagnosticStyle,
+    pub invalid_hint_diagnostic: DiagnosticStyle,
 }
 
 #[derive(Copy, Clone, Deserialize, Default)]
@@ -288,10 +290,14 @@ impl InputEditorStyle {
             line_number_active: Default::default(),
             guest_selections: Default::default(),
             syntax: Default::default(),
-            diagnostic_error: Default::default(),
-            diagnostic_warning: Default::default(),
-            diagnostic_information: Default::default(),
-            diagnostic_hint: Default::default(),
+            error_diagnostic: Default::default(),
+            invalid_error_diagnostic: Default::default(),
+            warning_diagnostic: Default::default(),
+            invalid_warning_diagnostic: Default::default(),
+            information_diagnostic: Default::default(),
+            invalid_information_diagnostic: Default::default(),
+            hint_diagnostic: Default::default(),
+            invalid_hint_diagnostic: Default::default(),
         }
     }
 }

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

@@ -173,7 +173,7 @@ corner_radius = 6
 
 [project_panel]
 extends = "$panel"
-padding.top = 6    # ($workspace.tab.height - $project_panel.entry.height) / 2
+padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2
 
 [project_panel.entry]
 text = "$text.1"
@@ -236,7 +236,11 @@ line_number_active = "$text.0.color"
 selection = "$selection.host"
 guest_selections = "$selection.guests"
 error_color = "$status.bad"
-diagnostic_error = { text = "$status.bad", border = "#ff0000", background = "#ffdddd" }
-diagnostic_warning = { text = "$status.warn", border = "#ffff00", background = "#ffffdd" }
-diagnostic_info = { text = "$status.info" }
-diagnostic_hint = { text = "$status.info" }
+error_diagnostic = { text = "$status.bad" }
+invalid_error_diagnostic = { text = "$text.3.color" }
+warning_diagnostic = { text = "$status.warn" }
+invalid_warning_diagnostic = { text = "$text.3.color" }
+information_diagnostic = { text = "$status.info" }
+invalid_information_diagnostic = { text = "$text.3.color" }
+hint_diagnostic = { text = "$status.info" }
+invalid_hint_diagnostic = { text = "$text.3.color" }