diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 6741cbc7e4..5ea0dcbd1d 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -697,34 +697,7 @@ fn diagnostic_header_renderer( diagnostic: Diagnostic, build_settings: BuildSettings, ) -> RenderBlock { - enum Run { - Text(Range), - Code(Range), - } - - 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) { + 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); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 47ba589823..cff35a7e32 100644 --- a/crates/editor/src/editor.rs +++ b/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(), }, diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 49a1f57d39..cc06d1fce4 100644 --- a/crates/theme/src/theme.rs +++ b/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(), diff --git a/crates/zed/assets/themes/_base.toml b/crates/zed/assets/themes/_base.toml index 9a221a2355..9acaafdacf 100644 --- a/crates/zed/assets/themes/_base.toml +++ b/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"