Don't apply completion's edit when it wouldn't change the buffer

Antonio Scandurra and Nathan Sobo created

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

Change summary

crates/editor/src/editor.rs   | 13 ++++++++-----
crates/language/src/buffer.rs |  4 +++-
2 files changed, 11 insertions(+), 6 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -1675,11 +1675,14 @@ impl Editor {
                 .log_err();
         } else {
             self.buffer.update(cx, |buffer, cx| {
-                buffer.edit_with_autoindent(
-                    [completion.old_range.clone()],
-                    &completion.new_text,
-                    cx,
-                );
+                let snapshot = buffer.read(cx);
+                let old_range = completion.old_range.to_offset(&snapshot);
+                if old_range.len() != completion.new_text.len()
+                    || !snapshot.contains_str_at(old_range.start, &completion.new_text)
+                {
+                    drop(snapshot);
+                    buffer.edit_with_autoindent([old_range], &completion.new_text, cx);
+                }
             });
         }
 

crates/language/src/buffer.rs 🔗

@@ -1888,7 +1888,9 @@ impl Buffer {
                     .await?;
                 if let Some(additional_edits) = resolved_completion.additional_text_edits {
                     this.update(&mut cx, |this, cx| {
-                        this.avoid_grouping_next_transaction();
+                        if !push_to_history {
+                            this.avoid_grouping_next_transaction();
+                        }
                         this.start_transaction();
                         let edit_ids = this.apply_lsp_edits(additional_edits, cx);
                         if let Some(transaction_id) = this.end_transaction(cx) {