Avoid building up pending edits when soft wrapping is disabled

Nathan Sobo and Antonio Scandurra created

This was causing us to get slower over time as we stacked up hundreds of thousands of pending edits whenever soft wrap was disabled.

Co-Authored-By: Antonio Scandurra <me@as-cii.com>

Change summary

crates/editor/src/display_map/wrap_map.rs | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)

Detailed changes

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

@@ -108,8 +108,16 @@ impl WrapMap {
         edits: Vec<TabEdit>,
         cx: &mut ModelContext<Self>,
     ) -> (Snapshot, Vec<Edit>) {
-        self.pending_edits.push_back((tab_snapshot, edits));
-        self.flush_edits(cx);
+        if self.wrap_width.is_some() {
+            self.pending_edits.push_back((tab_snapshot, edits));
+            self.flush_edits(cx);
+        } else {
+            self.edits_since_sync = self
+                .edits_since_sync
+                .compose(&self.snapshot.interpolate(tab_snapshot, &edits));
+            self.snapshot.interpolated = false;
+        }
+
         (
             self.snapshot.clone(),
             mem::take(&mut self.edits_since_sync).into_inner(),
@@ -1112,6 +1120,7 @@ mod tests {
                 while wrap_map.read_with(&cx, |map, _| map.is_rewrapping()) {
                     notifications.recv().await.unwrap();
                 }
+                wrap_map.read_with(&cx, |map, _| assert!(map.pending_edits.is_empty()));
             }
 
             if !wrap_map.read_with(&cx, |map, _| map.is_rewrapping()) {
@@ -1193,6 +1202,14 @@ mod tests {
             }
             assert_eq!(initial_text.to_string(), snapshot_text.to_string());
         }
+
+        if wrap_map.read_with(&cx, |map, _| map.is_rewrapping()) {
+            log::info!("Waiting for wrapping to finish");
+            while wrap_map.read_with(&cx, |map, _| map.is_rewrapping()) {
+                notifications.recv().await.unwrap();
+            }
+        }
+        wrap_map.read_with(&cx, |map, _| assert!(map.pending_edits.is_empty()));
     }
 
     fn wrap_text(