Fix more inlay_map corner cases and hangings

Kirill Bulatov and Antonio Scandurra created

Co-Authored-By: Antonio Scandurra <antonio@zed.dev>

Change summary

crates/editor/src/display_map/inlay_map.rs | 21 +++++++++++++++++++--
crates/editor/src/multi_buffer/anchor.rs   | 13 ++++---------
2 files changed, 23 insertions(+), 11 deletions(-)

Detailed changes

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

@@ -253,7 +253,7 @@ impl InlayMap {
     pub fn sync(
         &mut self,
         suggestion_snapshot: SuggestionSnapshot,
-        suggestion_edits: Vec<SuggestionEdit>,
+        mut suggestion_edits: Vec<SuggestionEdit>,
     ) -> (InlaySnapshot, Vec<InlayEdit>) {
         let mut snapshot = self.snapshot.lock();
 
@@ -262,6 +262,22 @@ impl InlayMap {
             new_snapshot.version += 1;
         }
 
+        if suggestion_snapshot
+            .buffer_snapshot()
+            .trailing_excerpt_update_count()
+            != snapshot
+                .suggestion_snapshot
+                .buffer_snapshot()
+                .trailing_excerpt_update_count()
+        {
+            if suggestion_edits.is_empty() {
+                suggestion_edits.push(Edit {
+                    old: snapshot.suggestion_snapshot.len()..snapshot.suggestion_snapshot.len(),
+                    new: suggestion_snapshot.len()..suggestion_snapshot.len(),
+                });
+            }
+        }
+
         let mut inlay_edits = Patch::default();
         let mut new_transforms = SumTree::new();
         let mut cursor = snapshot
@@ -393,7 +409,8 @@ impl InlayMap {
         to_remove: Vec<InlayId>,
         to_insert: Vec<(InlayId, InlayProperties<T>)>,
     ) -> (InlaySnapshot, Vec<InlayEdit>) {
-        let snapshot = self.snapshot.lock();
+        let mut snapshot = self.snapshot.lock();
+        snapshot.version += 1;
 
         let mut edits = BTreeSet::new();
         for (id, properties) in to_insert {

crates/editor/src/multi_buffer/anchor.rs 🔗

@@ -90,15 +90,10 @@ impl Anchor {
         if *self == Anchor::min() || *self == Anchor::max() {
             true
         } else if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) {
-            self.text_anchor.is_valid(&excerpt.buffer)
-                && self
-                    .text_anchor
-                    .cmp(&excerpt.range.context.start, &excerpt.buffer)
-                    .is_ge()
-                && self
-                    .text_anchor
-                    .cmp(&excerpt.range.context.end, &excerpt.buffer)
-                    .is_le()
+            excerpt.contains(self)
+                && (self.text_anchor == excerpt.range.context.start
+                    || self.text_anchor == excerpt.range.context.end
+                    || self.text_anchor.is_valid(&excerpt.buffer))
         } else {
             false
         }