diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index 9ebfdae5b0fec14f024acdbe0ddc8fb30299bbc2..e5b8d32818474f5a0926997789ac02b32d6ba4c7 100644 --- a/crates/editor/src/split.rs +++ b/crates/editor/src/split.rs @@ -1002,41 +1002,33 @@ impl SplittableEditor { cx: &mut Context, ) -> (Vec>, bool) { let rhs_display_map = self.rhs_editor.read(cx).display_map.clone(); - let lhs = &mut self.lhs; - let (anchors, added_a_new_excerpt) = - self.rhs_multibuffer.update(cx, |rhs_multibuffer, cx| { - let (anchors, added_a_new_excerpt) = rhs_multibuffer.set_excerpts_for_path( - path.clone(), - buffer.clone(), - ranges, - context_line_count, - cx, - ); - if !anchors.is_empty() - && rhs_multibuffer - .diff_for(buffer.read(cx).remote_id()) - .is_none_or(|old_diff| old_diff.entity_id() != diff.entity_id()) - { - rhs_multibuffer.add_diff(diff.clone(), cx); - } - - if let Some(lhs) = lhs { - lhs.multibuffer.update(cx, |lhs_multibuffer, lhs_cx| { - LhsEditor::sync_path_excerpts( - path, - rhs_multibuffer, - lhs_multibuffer, - diff, - &rhs_display_map, - lhs_cx, - ) - }) - } - - (anchors, added_a_new_excerpt) - }); - - (anchors, added_a_new_excerpt) + let lhs = self.lhs.as_ref(); + self.rhs_multibuffer.update(cx, |rhs_multibuffer, cx| { + mutate_excerpts_for_paths( + rhs_multibuffer, + lhs, + &rhs_display_map, + vec![(path.clone(), diff.clone())], + cx, + |rhs_multibuffer, cx| { + let (anchors, added_a_new_excerpt) = rhs_multibuffer.set_excerpts_for_path( + path.clone(), + buffer.clone(), + ranges, + context_line_count, + cx, + ); + if !anchors.is_empty() + && rhs_multibuffer + .diff_for(buffer.read(cx).remote_id()) + .is_none_or(|old_diff| old_diff.entity_id() != diff.entity_id()) + { + rhs_multibuffer.add_diff(diff.clone(), cx); + } + (anchors, added_a_new_excerpt) + }, + ) + }) } fn expand_excerpts( @@ -1047,37 +1039,35 @@ impl SplittableEditor { cx: &mut Context, ) { let rhs_display_map = self.rhs_editor.read(cx).display_map.clone(); - - let lhs = &mut self.lhs; - let lhs_multibuffer = lhs.as_ref().map(|l| l.multibuffer.clone()); + let lhs = self.lhs.as_ref(); self.rhs_multibuffer.update(cx, |rhs_multibuffer, cx| { - if let Some(lhs_multibuffer) = lhs_multibuffer { + if lhs.is_some() { let snapshot = rhs_multibuffer.snapshot(cx); - let affected_paths: HashMap<_, _> = excerpt_ids + let paths_with_diffs: Vec<_> = excerpt_ids .clone() - .map(|excerpt_id| { - let path = rhs_multibuffer.path_for_excerpt(excerpt_id).unwrap(); - let buffer = snapshot.buffer_for_excerpt(excerpt_id).unwrap(); - let diff = rhs_multibuffer.diff_for(buffer.remote_id()).unwrap(); - (path, diff) + .filter_map(|excerpt_id| { + let path = rhs_multibuffer.path_for_excerpt(excerpt_id)?; + let buffer = snapshot.buffer_for_excerpt(excerpt_id)?; + let diff = rhs_multibuffer.diff_for(buffer.remote_id())?; + Some((path, diff)) }) + .collect::>() + .into_iter() .collect(); - rhs_multibuffer.expand_excerpts(excerpt_ids.clone(), lines, direction, cx); - for (path, diff) in affected_paths { - lhs_multibuffer.update(cx, |lhs_multibuffer, lhs_cx| { - LhsEditor::sync_path_excerpts( - path, - rhs_multibuffer, - lhs_multibuffer, - diff, - &rhs_display_map, - lhs_cx, - ); - }); - } + + mutate_excerpts_for_paths( + rhs_multibuffer, + lhs, + &rhs_display_map, + paths_with_diffs, + cx, + |rhs_multibuffer, cx| { + rhs_multibuffer.expand_excerpts(excerpt_ids.clone(), lines, direction, cx); + }, + ); } else { - rhs_multibuffer.expand_excerpts(excerpt_ids.clone(), lines, direction, cx); - }; + rhs_multibuffer.expand_excerpts(excerpt_ids, lines, direction, cx); + } }); } @@ -1086,15 +1076,17 @@ impl SplittableEditor { if let Some(lhs) = &self.lhs { self.rhs_multibuffer.update(cx, |rhs_multibuffer, cx| { - lhs.multibuffer.update(cx, |lhs_multibuffer, cx| { - LhsEditor::remove_mappings_for_path( - &path, - rhs_multibuffer, - lhs_multibuffer, - &rhs_display_map, - cx, - ); - }); + let rhs_excerpt_ids: Vec = + rhs_multibuffer.excerpts_for_path(&path).collect(); + let lhs_excerpt_ids: Vec = + lhs.multibuffer.read(cx).excerpts_for_path(&path).collect(); + + if let Some(companion) = rhs_display_map.read(cx).companion().cloned() { + companion.update(cx, |c, _| { + c.remove_excerpt_mappings(lhs_excerpt_ids, rhs_excerpt_ids); + }); + } + rhs_multibuffer.remove_excerpts_for_path(path.clone(), cx); }); lhs.multibuffer.update(cx, |lhs_multibuffer, cx| { @@ -1938,6 +1930,44 @@ impl Render for SplittableEditor { } } +fn mutate_excerpts_for_paths( + rhs_multibuffer: &mut MultiBuffer, + lhs: Option<&LhsEditor>, + rhs_display_map: &Entity, + paths_with_diffs: Vec<(PathKey, Entity)>, + cx: &mut Context, + mutate: impl FnOnce(&mut MultiBuffer, &mut Context) -> R, +) -> R { + let old_rhs_ids: Vec<_> = paths_with_diffs + .iter() + .map(|(path, _)| { + rhs_multibuffer + .excerpts_for_path(path) + .collect::>() + }) + .collect(); + + let result = mutate(rhs_multibuffer, cx); + + if let Some(lhs) = lhs { + for ((path, diff), old_rhs_ids) in paths_with_diffs.into_iter().zip(old_rhs_ids) { + lhs.multibuffer.update(cx, |lhs_multibuffer, lhs_cx| { + LhsEditor::sync_path_excerpts( + path, + old_rhs_ids, + rhs_multibuffer, + lhs_multibuffer, + diff, + rhs_display_map, + lhs_cx, + ); + }); + } + } + + result +} + impl LhsEditor { fn update_path_excerpts_from_rhs( path_key: PathKey, @@ -2012,19 +2042,21 @@ impl LhsEditor { fn sync_path_excerpts( path_key: PathKey, + old_rhs_excerpt_ids: Vec, rhs_multibuffer: &MultiBuffer, lhs_multibuffer: &mut MultiBuffer, diff: Entity, rhs_display_map: &Entity, lhs_cx: &mut Context, ) { - Self::remove_mappings_for_path( - &path_key, - rhs_multibuffer, - lhs_multibuffer, - rhs_display_map, - lhs_cx, - ); + let old_lhs_excerpt_ids: Vec = + lhs_multibuffer.excerpts_for_path(&path_key).collect(); + + if let Some(companion) = rhs_display_map.read(lhs_cx).companion().cloned() { + companion.update(lhs_cx, |c, _| { + c.remove_excerpt_mappings(old_lhs_excerpt_ids, old_rhs_excerpt_ids); + }); + } let mappings = Self::update_path_excerpts_from_rhs( path_key, @@ -2046,23 +2078,6 @@ impl LhsEditor { }); } } - - fn remove_mappings_for_path( - path_key: &PathKey, - rhs_multibuffer: &MultiBuffer, - lhs_multibuffer: &MultiBuffer, - rhs_display_map: &Entity, - cx: &mut App, - ) { - let rhs_excerpt_ids: Vec = rhs_multibuffer.excerpts_for_path(path_key).collect(); - let lhs_excerpt_ids: Vec = lhs_multibuffer.excerpts_for_path(path_key).collect(); - - if let Some(companion) = rhs_display_map.read(cx).companion().cloned() { - companion.update(cx, |c, _| { - c.remove_excerpt_mappings(lhs_excerpt_ids, rhs_excerpt_ids); - }); - } - } } #[cfg(test)]