Detailed changes
  
  
    
    @@ -8,6 +8,7 @@ use crate::{
 use anyhow::Context as _;
 use smallvec::SmallVec;
 use std::{
+    borrow::Cow,
     cell::{Cell, RefCell},
     mem,
     ops::Range,
@@ -334,12 +335,11 @@ impl TextLayout {
             .line_height
             .to_pixels(font_size.into(), window.rem_size());
 
-        let mut runs = if let Some(runs) = runs {
+        let runs = if let Some(runs) = runs {
             runs
         } else {
             vec![text_style.to_run(text.len())]
         };
-
         window.request_measured_layout(Default::default(), {
             let element_state = self.clone();
 
@@ -378,15 +378,15 @@ impl TextLayout {
                 }
 
                 let mut line_wrapper = cx.text_system().line_wrapper(text_style.font(), font_size);
-                let text = if let Some(truncate_width) = truncate_width {
+                let (text, runs) = if let Some(truncate_width) = truncate_width {
                     line_wrapper.truncate_line(
                         text.clone(),
                         truncate_width,
                         &truncation_suffix,
-                        &mut runs,
+                        &runs,
                     )
                 } else {
-                    text.clone()
+                    (text.clone(), Cow::Borrowed(&*runs))
                 };
                 let len = text.len();
 
  
  
  
    
    @@ -9,7 +9,6 @@ pub use gpui_macros::{
     overflow_style_methods, padding_style_methods, position_style_methods,
     visibility_style_methods,
 };
-
 const ELLIPSIS: SharedString = SharedString::new_static("…");
 
 /// A trait for elements that can be styled.
  
  
  
    
    @@ -418,22 +418,21 @@ impl WindowTextSystem {
         let mut font_runs = self.font_runs_pool.lock().pop().unwrap_or_default();
 
         let mut lines = SmallVec::new();
-        let mut line_start = 0;
-        let mut max_wrap_lines = line_clamp.unwrap_or(usize::MAX);
+        let mut max_wrap_lines = line_clamp;
         let mut wrapped_lines = 0;
 
-        let mut process_line = |line_text: SharedString| {
+        let mut process_line = |line_text: SharedString, line_start, line_end| {
             font_runs.clear();
-            let line_end = line_start + line_text.len();
 
             let mut decoration_runs = SmallVec::<[DecorationRun; 32]>::new();
             let mut run_start = line_start;
             while run_start < line_end {
                 let Some(run) = runs.peek_mut() else {
+                    log::warn!("`TextRun`s do not cover the entire to be shaped text");
                     break;
                 };
 
-                let run_len_within_line = cmp::min(line_end, run_start + run.len) - run_start;
+                let run_len_within_line = cmp::min(line_end - run_start, run.len);
 
                 let decoration_changed = if let Some(last_run) = decoration_runs.last_mut()
                     && last_run.color == run.color
@@ -467,11 +466,10 @@ impl WindowTextSystem {
                     });
                 }
 
-                if run_len_within_line == run.len {
+                // Preserve the remainder of the run for the next line
+                run.len -= run_len_within_line;
+                if run.len == 0 {
                     runs.next();
-                } else {
-                    // Preserve the remainder of the run for the next line
-                    run.len -= run_len_within_line;
                 }
                 run_start += run_len_within_line;
             }
@@ -481,7 +479,7 @@ impl WindowTextSystem {
                 font_size,
                 &font_runs,
                 wrap_width,
-                Some(max_wrap_lines - wrapped_lines),
+                max_wrap_lines.map(|max| max.saturating_sub(wrapped_lines)),
             );
             wrapped_lines += layout.wrap_boundaries.len();
 
@@ -492,7 +490,6 @@ impl WindowTextSystem {
             });
 
             // Skip `\n` character.
-            line_start = line_end + 1;
             if let Some(run) = runs.peek_mut() {
                 run.len -= 1;
                 if run.len == 0 {
@@ -502,21 +499,34 @@ impl WindowTextSystem {
         };
 
         let mut split_lines = text.split('\n');
-        let mut processed = false;
 
+        // Special case single lines to prevent allocating a sharedstring
         if let Some(first_line) = split_lines.next()
             && let Some(second_line) = split_lines.next()
         {
-            processed = true;
-            process_line(first_line.to_string().into());
-            process_line(second_line.to_string().into());
+            let mut line_start = 0;
+            process_line(
+                SharedString::new(first_line),
+                line_start,
+                line_start + first_line.len(),
+            );
+            line_start += first_line.len() + '\n'.len_utf8();
+            process_line(
+                SharedString::new(second_line),
+                line_start,
+                line_start + second_line.len(),
+            );
             for line_text in split_lines {
-                process_line(line_text.to_string().into());
+                line_start += line_text.len() + '\n'.len_utf8();
+                process_line(
+                    SharedString::new(line_text),
+                    line_start,
+                    line_start + line_text.len(),
+                );
             }
-        }
-
-        if !processed {
-            process_line(text);
+        } else {
+            let end = text.len();
+            process_line(text, 0, end);
         }
 
         self.font_runs_pool.lock().push(font_runs);
  
  
  
    
    @@ -1,6 +1,6 @@
 use crate::{FontId, FontRun, Pixels, PlatformTextSystem, SharedString, TextRun, px};
 use collections::HashMap;
-use std::{iter, sync::Arc};
+use std::{borrow::Cow, iter, sync::Arc};
 
 /// The GPUI line wrapper, used to wrap lines of text to a given width.
 pub struct LineWrapper {
@@ -129,13 +129,13 @@ impl LineWrapper {
     }
 
     /// Truncate a line of text to the given width with this wrapper's font and font size.
-    pub fn truncate_line(
+    pub fn truncate_line<'a>(
         &mut self,
         line: SharedString,
         truncate_width: Pixels,
         truncation_suffix: &str,
-        runs: &mut Vec<TextRun>,
-    ) -> SharedString {
+        runs: &'a [TextRun],
+    ) -> (SharedString, Cow<'a, [TextRun]>) {
         let mut width = px(0.);
         let mut suffix_width = truncation_suffix
             .chars()
@@ -154,13 +154,14 @@ impl LineWrapper {
             if width.floor() > truncate_width {
                 let result =
                     SharedString::from(format!("{}{}", &line[..truncate_ix], truncation_suffix));
-                update_runs_after_truncation(&result, truncation_suffix, runs);
+                let mut runs = runs.to_vec();
+                update_runs_after_truncation(&result, truncation_suffix, &mut runs);
 
-                return result;
+                return (result, Cow::Owned(runs));
             }
         }
 
-        line
+        (line, Cow::Borrowed(runs))
     }
 
     /// Any character in this list should be treated as a word character,
@@ -493,15 +494,14 @@ mod tests {
         fn perform_test(
             wrapper: &mut LineWrapper,
             text: &'static str,
-            result: &'static str,
+            expected: &'static str,
             ellipsis: &str,
         ) {
             let dummy_run_lens = vec![text.len()];
-            let mut dummy_runs = generate_test_runs(&dummy_run_lens);
-            assert_eq!(
-                wrapper.truncate_line(text.into(), px(220.), ellipsis, &mut dummy_runs),
-                result
-            );
+            let dummy_runs = generate_test_runs(&dummy_run_lens);
+            let (result, dummy_runs) =
+                wrapper.truncate_line(text.into(), px(220.), ellipsis, &dummy_runs);
+            assert_eq!(result, expected);
             assert_eq!(dummy_runs.first().unwrap().len, result.len());
         }
 
@@ -532,16 +532,15 @@ mod tests {
         fn perform_test(
             wrapper: &mut LineWrapper,
             text: &'static str,
-            result: &str,
+            expected: &str,
             run_lens: &[usize],
             result_run_len: &[usize],
             line_width: Pixels,
         ) {
-            let mut dummy_runs = generate_test_runs(run_lens);
-            assert_eq!(
-                wrapper.truncate_line(text.into(), line_width, "…", &mut dummy_runs),
-                result
-            );
+            let dummy_runs = generate_test_runs(run_lens);
+            let (result, dummy_runs) =
+                wrapper.truncate_line(text.into(), line_width, "…", &dummy_runs);
+            assert_eq!(result, expected);
             for (run, result_len) in dummy_runs.iter().zip(result_run_len) {
                 assert_eq!(run.len, *result_len);
             }
  
  
  
    
    @@ -3243,14 +3243,11 @@ impl Window {
     /// returns a `Size`.
     ///
     /// This method should only be called as part of the request_layout or prepaint phase of element drawing.
-    pub fn request_measured_layout<
-        F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut Window, &mut App) -> Size<Pixels>
+    pub fn request_measured_layout<F>(&mut self, style: Style, measure: F) -> LayoutId
+    where
+        F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>, &mut Window, &mut App) -> Size<Pixels>
             + 'static,
-    >(
-        &mut self,
-        style: Style,
-        measure: F,
-    ) -> LayoutId {
+    {
         self.invalidator.debug_assert_prepaint();
 
         let rem_size = self.rem_size();