Avoid unnecessary code action requests when applying leader updates to an editor

This commit is contained in:
Max Brunsfeld 2023-05-18 14:46:23 -07:00
parent 2883d6f1ef
commit 58f704abcb
2 changed files with 43 additions and 4 deletions

View file

@ -5517,10 +5517,12 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
}); });
let is_still_following = Rc::new(RefCell::new(true)); let is_still_following = Rc::new(RefCell::new(true));
let follower_edit_event_count = Rc::new(RefCell::new(0));
let pending_update = Rc::new(RefCell::new(None)); let pending_update = Rc::new(RefCell::new(None));
follower.update(cx, { follower.update(cx, {
let update = pending_update.clone(); let update = pending_update.clone();
let is_still_following = is_still_following.clone(); let is_still_following = is_still_following.clone();
let follower_edit_event_count = follower_edit_event_count.clone();
|_, cx| { |_, cx| {
cx.subscribe(&leader, move |_, leader, event, cx| { cx.subscribe(&leader, move |_, leader, event, cx| {
leader leader
@ -5533,6 +5535,9 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
if Editor::should_unfollow_on_event(event, cx) { if Editor::should_unfollow_on_event(event, cx) {
*is_still_following.borrow_mut() = false; *is_still_following.borrow_mut() = false;
} }
if let Event::BufferEdited = event {
*follower_edit_event_count.borrow_mut() += 1;
}
}) })
.detach(); .detach();
} }
@ -5552,6 +5557,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
assert_eq!(follower.selections.ranges(cx), vec![1..1]); assert_eq!(follower.selections.ranges(cx), vec![1..1]);
}); });
assert_eq!(*is_still_following.borrow(), true); assert_eq!(*is_still_following.borrow(), true);
assert_eq!(*follower_edit_event_count.borrow(), 0);
// Update the scroll position only // Update the scroll position only
leader.update(cx, |leader, cx| { leader.update(cx, |leader, cx| {
@ -5568,6 +5574,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
vec2f(1.5, 3.5) vec2f(1.5, 3.5)
); );
assert_eq!(*is_still_following.borrow(), true); assert_eq!(*is_still_following.borrow(), true);
assert_eq!(*follower_edit_event_count.borrow(), 0);
// Update the selections and scroll position. The follower's scroll position is updated // Update the selections and scroll position. The follower's scroll position is updated
// via autoscroll, not via the leader's exact scroll position. // via autoscroll, not via the leader's exact scroll position.

View file

@ -1167,6 +1167,9 @@ impl MultiBuffer {
) { ) {
self.sync(cx); self.sync(cx);
let ids = excerpt_ids.into_iter().collect::<Vec<_>>(); let ids = excerpt_ids.into_iter().collect::<Vec<_>>();
if ids.is_empty() {
return;
}
let mut buffers = self.buffers.borrow_mut(); let mut buffers = self.buffers.borrow_mut();
let mut snapshot = self.snapshot.borrow_mut(); let mut snapshot = self.snapshot.borrow_mut();
@ -4100,19 +4103,25 @@ mod tests {
let leader_multibuffer = cx.add_model(|_| MultiBuffer::new(0)); let leader_multibuffer = cx.add_model(|_| MultiBuffer::new(0));
let follower_multibuffer = cx.add_model(|_| MultiBuffer::new(0)); let follower_multibuffer = cx.add_model(|_| MultiBuffer::new(0));
let follower_edit_event_count = Rc::new(RefCell::new(0));
follower_multibuffer.update(cx, |_, cx| { follower_multibuffer.update(cx, |_, cx| {
cx.subscribe(&leader_multibuffer, |follower, _, event, cx| { let follower_edit_event_count = follower_edit_event_count.clone();
match event.clone() { cx.subscribe(
&leader_multibuffer,
move |follower, _, event, cx| match event.clone() {
Event::ExcerptsAdded { Event::ExcerptsAdded {
buffer, buffer,
predecessor, predecessor,
excerpts, excerpts,
} => follower.insert_excerpts_with_ids_after(predecessor, buffer, excerpts, cx), } => follower.insert_excerpts_with_ids_after(predecessor, buffer, excerpts, cx),
Event::ExcerptsRemoved { ids } => follower.remove_excerpts(ids, cx), Event::ExcerptsRemoved { ids } => follower.remove_excerpts(ids, cx),
_ => {} Event::Edited => {
*follower_edit_event_count.borrow_mut() += 1;
} }
}) _ => {}
},
)
.detach(); .detach();
}); });
@ -4151,6 +4160,7 @@ mod tests {
leader_multibuffer.read(cx).snapshot(cx).text(), leader_multibuffer.read(cx).snapshot(cx).text(),
follower_multibuffer.read(cx).snapshot(cx).text(), follower_multibuffer.read(cx).snapshot(cx).text(),
); );
assert_eq!(*follower_edit_event_count.borrow(), 2);
leader_multibuffer.update(cx, |leader, cx| { leader_multibuffer.update(cx, |leader, cx| {
let excerpt_ids = leader.excerpt_ids(); let excerpt_ids = leader.excerpt_ids();
@ -4160,6 +4170,27 @@ mod tests {
leader_multibuffer.read(cx).snapshot(cx).text(), leader_multibuffer.read(cx).snapshot(cx).text(),
follower_multibuffer.read(cx).snapshot(cx).text(), follower_multibuffer.read(cx).snapshot(cx).text(),
); );
assert_eq!(*follower_edit_event_count.borrow(), 3);
// Removing an empty set of excerpts is a noop.
leader_multibuffer.update(cx, |leader, cx| {
leader.remove_excerpts([], cx);
});
assert_eq!(
leader_multibuffer.read(cx).snapshot(cx).text(),
follower_multibuffer.read(cx).snapshot(cx).text(),
);
assert_eq!(*follower_edit_event_count.borrow(), 3);
// Adding an empty set of excerpts is a noop.
leader_multibuffer.update(cx, |leader, cx| {
leader.push_excerpts::<usize>(buffer_2.clone(), [], cx);
});
assert_eq!(
leader_multibuffer.read(cx).snapshot(cx).text(),
follower_multibuffer.read(cx).snapshot(cx).text(),
);
assert_eq!(*follower_edit_event_count.borrow(), 3);
leader_multibuffer.update(cx, |leader, cx| { leader_multibuffer.update(cx, |leader, cx| {
leader.clear(cx); leader.clear(cx);
@ -4168,6 +4199,7 @@ mod tests {
leader_multibuffer.read(cx).snapshot(cx).text(), leader_multibuffer.read(cx).snapshot(cx).text(),
follower_multibuffer.read(cx).snapshot(cx).text(), follower_multibuffer.read(cx).snapshot(cx).text(),
); );
assert_eq!(*follower_edit_event_count.borrow(), 4);
} }
#[gpui::test] #[gpui::test]