From 70cb2fa8d73ab0b2ccdcd5ba5b01f1c45aafd8ec Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 1 Mar 2023 10:17:04 -0800 Subject: [PATCH] Apply external command formatting if buffer has changed while computing it --- crates/language/src/buffer.rs | 46 ++++++++++------------------- crates/language/src/buffer_tests.rs | 2 +- crates/project/src/project.rs | 2 +- 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 5d7e4325d15af8f59af549bb4253b428d68fbc39..acccb553d3d14d11e6140fb8e2a81818214e84e1 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -569,20 +569,21 @@ impl Buffer { .read_with(&cx, |this, cx| this.diff(new_text, cx)) .await; this.update(&mut cx, |this, cx| { - this.finalize_last_transaction(); - this.apply_diff(diff, cx); - if let Some(transaction) = this.finalize_last_transaction().cloned() { - this.did_reload( - this.version(), - this.as_rope().fingerprint(), - this.line_ending(), - new_mtime, - cx, - ); - Ok(Some(transaction)) - } else { - Ok(None) + if this.version() == diff.base_version { + this.finalize_last_transaction(); + this.apply_diff(diff, cx); + if let Some(transaction) = this.finalize_last_transaction().cloned() { + this.did_reload( + this.version(), + this.as_rope().fingerprint(), + this.line_ending(), + new_mtime, + cx, + ); + return Ok(Some(transaction)); + } } + Ok(None) }) } else { Ok(None) @@ -1197,25 +1198,10 @@ impl Buffer { self.edit([(offset..len, "\n")], None, cx); } - pub fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext) -> Option { - if self.version == diff.base_version { - self.start_transaction(); - self.text.set_line_ending(diff.line_ending); - self.edit(diff.edits, None, cx); - self.end_transaction(cx) - } else { - return None; - } - } - /// Apply a diff to the buffer. If the buffer has changed since the given diff was /// calculated, then adjust the diff to account for those changes, and discard any /// parts of the diff that conflict with those changes. - pub fn apply_non_conflicting_portion_of_diff( - &mut self, - diff: Diff, - cx: &mut ModelContext, - ) -> Option { + pub fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext) -> Option { // Check for any edits to the buffer that have occurred since this diff // was computed. let snapshot = self.snapshot(); @@ -1223,7 +1209,7 @@ impl Buffer { let mut delta = 0; let adjusted_edits = diff.edits.into_iter().filter_map(|(range, new_text)| { while let Some(edit_since) = edits_since.peek() { - // If the edit occurs after a diff hunk, then it can does not + // If the edit occurs after a diff hunk, then it does not // affect that hunk. if edit_since.old.start > range.end { break; diff --git a/crates/language/src/buffer_tests.rs b/crates/language/src/buffer_tests.rs index c7fc25d793ac0d16d4904a504c38181545775fa4..0c375f0f4e1e27e59bbc737443307ae1b9c94c66 100644 --- a/crates/language/src/buffer_tests.rs +++ b/crates/language/src/buffer_tests.rs @@ -254,7 +254,7 @@ async fn test_normalize_whitespace(cx: &mut gpui::TestAppContext) { let format_diff = format.await; buffer.update(cx, |buffer, cx| { let version_before_format = format_diff.base_version.clone(); - buffer.apply_non_conflicting_portion_of_diff(format_diff, cx); + buffer.apply_diff(format_diff, cx); // The outcome depends on the order of concurrent taks. // diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index cadbde0bac9a5bbc8f05b6966e0e6c9d8d492766..0325d07ce6a38991b31f27ff31895c6d4cb0061a 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2921,7 +2921,7 @@ impl Project { buffer.finalize_last_transaction(); buffer.start_transaction(); if let Some(diff) = trailing_whitespace_diff { - buffer.apply_non_conflicting_portion_of_diff(diff, cx); + buffer.apply_diff(diff, cx); } if ensure_final_newline { buffer.ensure_final_newline(cx);