Format messages within backticks using bold instead of with a background

Antonio Scandurra created

Change summary

crates/diagnostics/src/diagnostics.rs | 77 ++++++++++------------------
crates/editor/src/editor.rs           | 17 +++---
crates/theme/src/theme.rs             | 10 +--
crates/zed/assets/themes/_base.toml   | 11 +---
4 files changed, 45 insertions(+), 70 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -697,34 +697,7 @@ fn diagnostic_header_renderer(
     diagnostic: Diagnostic,
     build_settings: BuildSettings,
 ) -> RenderBlock {
-    enum Run {
-        Text(Range<usize>),
-        Code(Range<usize>),
-    }
-
-    let mut prev_ix = 0;
-    let mut inside_block = false;
-    let mut runs = Vec::new();
-    for (backtick_ix, _) in diagnostic.message.match_indices('`') {
-        if backtick_ix > prev_ix {
-            if inside_block {
-                runs.push(Run::Code(prev_ix..backtick_ix));
-            } else {
-                runs.push(Run::Text(prev_ix..backtick_ix));
-            }
-        }
-
-        inside_block = !inside_block;
-        prev_ix = backtick_ix + 1;
-    }
-    if prev_ix < diagnostic.message.len() {
-        if inside_block {
-            runs.push(Run::Code(prev_ix..diagnostic.message.len()));
-        } else {
-            runs.push(Run::Text(prev_ix..diagnostic.message.len()));
-        }
-    }
-
+    let (message, highlights) = highlight_diagnostic_message(&diagnostic.message);
     Arc::new(move |cx| {
         let settings = build_settings(cx);
         let style = &settings.style.diagnostic_header;
@@ -745,28 +718,14 @@ fn diagnostic_header_renderer(
                     .with_style(style.icon.container)
                     .boxed(),
             )
-            .with_children(runs.iter().map(|run| {
-                let container_style;
-                let text_style;
-                let range;
-                match run {
-                    Run::Text(run_range) => {
-                        container_style = Default::default();
-                        text_style = style.text.clone();
-                        range = run_range.clone();
-                    }
-                    Run::Code(run_range) => {
-                        container_style = style.highlighted_text.container;
-                        text_style = style.highlighted_text.text.clone();
-                        range = run_range.clone();
-                    }
-                }
-                Label::new(diagnostic.message[range].to_string(), text_style)
+            .with_child(
+                Label::new(message.clone(), style.message.label.clone())
+                    .with_highlights(highlights.clone())
                     .contained()
-                    .with_style(container_style)
+                    .with_style(style.message.container)
                     .aligned()
-                    .boxed()
-            }))
+                    .boxed(),
+            )
             .with_children(diagnostic.code.clone().map(|code| {
                 Label::new(code, style.code.text.clone())
                     .contained()
@@ -782,6 +741,28 @@ fn diagnostic_header_renderer(
     })
 }
 
+fn highlight_diagnostic_message(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();
+    for (match_ix, (offset, _)) in message
+        .match_indices('`')
+        .chain([(message.len(), "")])
+        .enumerate()
+    {
+        message_without_backticks.push_str(&message[prev_offset..offset]);
+        if inside_block {
+            highlights.extend(prev_offset - match_ix..offset - match_ix);
+        }
+
+        inside_block = !inside_block;
+        prev_offset = offset + 1;
+    }
+
+    (message_without_backticks, highlights)
+}
+
 fn context_header_renderer(build_settings: BuildSettings) -> RenderBlock {
     Arc::new(move |cx| {
         let settings = build_settings(cx);

crates/editor/src/editor.rs 🔗

@@ -3803,6 +3803,8 @@ impl Deref for EditorSnapshot {
 impl EditorSettings {
     #[cfg(any(test, feature = "test-support"))]
     pub fn test(cx: &AppContext) -> Self {
+        use theme::{ContainedLabel, ContainedText, DiagnosticHeader, DiagnosticPathHeader};
+
         Self {
             tab_size: 4,
             soft_wrap: SoftWrap::None,
@@ -3835,25 +3837,24 @@ impl EditorSettings {
                     selection: Default::default(),
                     guest_selections: Default::default(),
                     syntax: Default::default(),
-                    diagnostic_path_header: theme::DiagnosticPathHeader {
+                    diagnostic_path_header: DiagnosticPathHeader {
                         container: Default::default(),
-                        filename: theme::ContainedText {
+                        filename: ContainedText {
                             container: Default::default(),
                             text: text.clone(),
                         },
-                        path: theme::ContainedText {
+                        path: ContainedText {
                             container: Default::default(),
                             text: text.clone(),
                         },
                     },
-                    diagnostic_header: theme::DiagnosticHeader {
+                    diagnostic_header: DiagnosticHeader {
                         container: Default::default(),
-                        text: text.clone(),
-                        highlighted_text: theme::ContainedText {
+                        message: ContainedLabel {
                             container: Default::default(),
-                            text: text.clone(),
+                            label: text.clone().into(),
                         },
-                        code: theme::ContainedText {
+                        code: ContainedText {
                             container: Default::default(),
                             text: text.clone(),
                         },

crates/theme/src/theme.rs 🔗

@@ -221,7 +221,7 @@ pub struct ContainedText {
     pub text: TextStyle,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Clone, Deserialize, Default)]
 pub struct ContainedLabel {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -275,8 +275,7 @@ pub struct DiagnosticPathHeader {
 pub struct DiagnosticHeader {
     #[serde(flatten)]
     pub container: ContainerStyle,
-    pub text: TextStyle,
-    pub highlighted_text: ContainedText,
+    pub message: ContainedLabel,
     pub code: ContainedText,
     pub icon: DiagnosticHeaderIcon,
 }
@@ -356,10 +355,9 @@ impl InputEditorStyle {
             },
             diagnostic_header: DiagnosticHeader {
                 container: Default::default(),
-                text: self.text.clone(),
-                highlighted_text: ContainedText {
+                message: ContainedLabel {
                     container: Default::default(),
-                    text: self.text.clone(),
+                    label: self.text.clone().into(),
                 },
                 code: ContainedText {
                     container: Default::default(),

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

@@ -263,17 +263,12 @@ path = { extends = "$text.2", size = 14, margin.left = 12 }
 [editor.diagnostic_header]
 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]
-extends = "$editor.diagnostic_header.text"
-color = "$text.0.color"
-background = "#ffffff1f"
-padding.left = 3
-padding.right = 3
-corner_radius = 3
+[editor.diagnostic_header.message]
+text = { extends = "$text.1", size = 14 }
+highlight_text = { extends = "$text.0", size = 14, weight = "bold" }
 
 [editor.error_diagnostic]
 text = "$status.bad"