From 781fff220c4e282c973d48e4f4dae909a760411e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Oct 2024 08:36:21 -0600 Subject: [PATCH] Fix merging of an update of a symbol with an insert_before operation before the same symbol (#19450) When we insert before some text and then update that same text, we need to preserve and concatenate the new text associated with both operations. Release Notes: - N/A --- crates/assistant/src/patch.rs | 87 ++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/crates/assistant/src/patch.rs b/crates/assistant/src/patch.rs index 82c81d3b86..8e6430f534 100644 --- a/crates/assistant/src/patch.rs +++ b/crates/assistant/src/patch.rs @@ -146,12 +146,28 @@ impl ResolvedEdit { return false; } - if let Some(description) = &mut self.description { - if let Some(other_description) = &other.description { + let other_offset_range = other_range.to_offset(buffer); + let offset_range = range.to_offset(buffer); + + // If the other range is empty at the start of this edit's range, combine the new text + if other_offset_range.is_empty() && other_offset_range.start == offset_range.start { + self.new_text = format!("{}\n{}", other.new_text, self.new_text); + self.range.start = other_range.start; + + if let Some((description, other_description)) = + self.description.as_mut().zip(other.description.as_ref()) + { + *description = format!("{}\n{}", other_description, description) + } + } else { + if let Some((description, other_description)) = + self.description.as_mut().zip(other.description.as_ref()) + { description.push('\n'); description.push_str(other_description); } } + true } } @@ -699,6 +715,73 @@ mod tests { .unindent(), cx, ); + + // Ensure InsertBefore merges correctly with Update of the same text + + assert_edits( + " + fn foo() { + + } + " + .unindent(), + vec![ + AssistantEditKind::InsertBefore { + old_text: " + fn foo() {" + .unindent(), + new_text: " + fn bar() { + qux(); + }" + .unindent(), + description: "implement bar".into(), + }, + AssistantEditKind::Update { + old_text: " + fn foo() { + + }" + .unindent(), + new_text: " + fn foo() { + bar(); + }" + .unindent(), + description: "call bar in foo".into(), + }, + AssistantEditKind::InsertAfter { + old_text: " + fn foo() { + + } + " + .unindent(), + new_text: " + fn qux() { + // todo + } + " + .unindent(), + description: "implement qux".into(), + }, + ], + " + fn bar() { + qux(); + } + + fn foo() { + bar(); + } + + fn qux() { + // todo + } + " + .unindent(), + cx, + ); } #[track_caller]