Polish rendering of inline errors

Antonio Scandurra and Nathan Sobo created

- Don't soft-wrap
- Render multiple lines

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

Change summary

crates/diagnostics/src/diagnostics.rs |  2 +-
crates/editor/src/editor.rs           |  7 ++++++-
crates/gpui/src/elements/text.rs      | 22 ++++++++++++++++++----
3 files changed, 25 insertions(+), 6 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -285,7 +285,7 @@ impl ProjectDiagnosticsEditor {
                                 diagnostic_blocks.push(DiagnosticBlock::Header(primary.clone()));
                                 blocks_to_add.push(BlockProperties {
                                     position: header_position,
-                                    height: 2,
+                                    height: primary.message.matches('\n').count() as u8 + 2,
                                     render: diagnostic_header_renderer(
                                         buffer.clone(),
                                         primary.clone(),

crates/editor/src/editor.rs 🔗

@@ -3800,6 +3800,7 @@ pub fn diagnostic_block_renderer(
         let mut text_style = settings.style.text.clone();
         text_style.color = diagnostic_style(diagnostic.severity, is_valid, &settings.style).text;
         Text::new(diagnostic.message.clone(), text_style)
+            .with_soft_wrap(false)
             .contained()
             .with_margin_left(cx.anchor_x)
             .boxed()
@@ -3823,7 +3824,11 @@ pub fn diagnostic_header_renderer(
         };
 
         Flex::column()
-            .with_child(Label::new(diagnostic.message.clone(), text_style).boxed())
+            .with_child(
+                Text::new(diagnostic.message.clone(), text_style)
+                    .with_soft_wrap(false)
+                    .boxed(),
+            )
             .with_child(Label::new(file_path, settings.style.text.clone()).boxed())
             .boxed()
     })

crates/gpui/src/elements/text.rs 🔗

@@ -14,6 +14,7 @@ use serde_json::json;
 pub struct Text {
     text: String,
     style: TextStyle,
+    soft_wrap: bool,
 }
 
 pub struct LayoutState {
@@ -23,13 +24,22 @@ pub struct LayoutState {
 
 impl Text {
     pub fn new(text: String, style: TextStyle) -> Self {
-        Self { text, style }
+        Self {
+            text,
+            style,
+            soft_wrap: true,
+        }
     }
 
     pub fn with_default_color(mut self, color: Color) -> Self {
         self.style.color = color;
         self
     }
+
+    pub fn with_soft_wrap(mut self, soft_wrap: bool) -> Self {
+        self.soft_wrap = soft_wrap;
+        self
+    }
 }
 
 impl Element for Text {
@@ -54,9 +64,13 @@ impl Element for Text {
                 self.style.font_size,
                 &[(line.len(), self.style.to_run())],
             );
-            let wrap_boundaries = wrapper
-                .wrap_shaped_line(line, &shaped_line, constraint.max.x())
-                .collect::<Vec<_>>();
+            let wrap_boundaries = if self.soft_wrap {
+                wrapper
+                    .wrap_shaped_line(line, &shaped_line, constraint.max.x())
+                    .collect::<Vec<_>>()
+            } else {
+                Vec::new()
+            };
 
             max_line_width = max_line_width.max(shaped_line.width());
             line_count += wrap_boundaries.len() + 1;