Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/syntax_editor/edit_algo.rs')
-rw-r--r--crates/syntax/src/syntax_editor/edit_algo.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs
index 01c1f0d49b..d54837b9f2 100644
--- a/crates/syntax/src/syntax_editor/edit_algo.rs
+++ b/crates/syntax/src/syntax_editor/edit_algo.rs
@@ -150,6 +150,15 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
// Map change targets to the correct syntax nodes
let tree_mutator = TreeMutator::new(&root);
let mut changed_elements = vec![];
+ let mut changed_elements_set = rustc_hash::FxHashSet::default();
+ let mut deduplicate_node = |node_or_token: &mut SyntaxElement| {
+ let SyntaxElement::Node(node) = node_or_token else { return };
+ if changed_elements_set.contains(node) {
+ *node = node.clone_subtree().clone_for_update();
+ } else {
+ changed_elements_set.insert(node.clone());
+ }
+ };
for index in independent_changes {
match &mut changes[index as usize] {
@@ -180,6 +189,18 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
}
}
+ match &mut changes[index as usize] {
+ Change::Insert(_, element) | Change::Replace(_, Some(element)) => {
+ deduplicate_node(element);
+ }
+ Change::InsertAll(_, elements)
+ | Change::ReplaceWithMany(_, elements)
+ | Change::ReplaceAll(_, elements) => {
+ elements.iter_mut().for_each(&mut deduplicate_node);
+ }
+ Change::Replace(_, None) => (),
+ }
+
// Collect changed elements
match &changes[index as usize] {
Change::Insert(_, element) => changed_elements.push(element.clone()),