Skip to content

Commit b21f4a3

Browse files
Prevent remote edits from triggering edit predictions when collaborating (#51196)
BufferEvent::Edited had no way to distinguish local edits from remote (collaboration) edits. This caused edit prediction behavior to fire on the guest's editor when the host made document changes. Release Notes: - Fixed edit predictions triggering on collaboration guests when the host edits the document. --------- Co-authored-by: Ben Kunkle <ben@zed.dev>
1 parent eae21de commit b21f4a3

17 files changed

Lines changed: 72 additions & 39 deletions

File tree

crates/action_log/src/action_log.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ impl ActionLog {
209209
cx: &mut Context<Self>,
210210
) {
211211
match event {
212-
BufferEvent::Edited => {
212+
BufferEvent::Edited { .. } => {
213213
let Some(tracked_buffer) = self.tracked_buffers.get_mut(&buffer) else {
214214
return;
215215
};

crates/assistant_text_thread/src/text_thread.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ impl TextThread {
12191219
} => cx.emit(TextThreadEvent::Operation(
12201220
TextThreadOperation::BufferOperation(operation.clone()),
12211221
)),
1222-
language::BufferEvent::Edited => {
1222+
language::BufferEvent::Edited { .. } => {
12231223
self.count_remaining_tokens(cx);
12241224
self.reparse(cx);
12251225
cx.emit(TextThreadEvent::MessagesEdited);

crates/channel/src/channel_buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ impl ChannelBuffer {
221221
})
222222
.log_err();
223223
}
224-
language::BufferEvent::Edited => {
224+
language::BufferEvent::Edited { .. } => {
225225
cx.emit(ChannelBufferEvent::BufferEdited);
226226
}
227227
_ => {}

crates/copilot/src/copilot.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ impl Copilot {
949949
&& let Some(registered_buffer) = server.registered_buffers.get_mut(&buffer.entity_id())
950950
{
951951
match event {
952-
language::BufferEvent::Edited => {
952+
language::BufferEvent::Edited { .. } => {
953953
drop(registered_buffer.report_changes(&buffer, cx));
954954
}
955955
language::BufferEvent::Saved => {

crates/edit_prediction/src/edit_prediction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ impl EditPredictionStore {
12171217
cx.subscribe(buffer, {
12181218
let project = project.downgrade();
12191219
move |this, buffer, event, cx| {
1220-
if let language::BufferEvent::Edited = event
1220+
if let language::BufferEvent::Edited { .. } = event
12211221
&& let Some(project) = project.upgrade()
12221222
{
12231223
this.report_changes_for_buffer(&buffer, &project, false, cx);

crates/editor/src/editor.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24128,7 +24128,10 @@ impl Editor {
2412824128
cx: &mut Context<Self>,
2412924129
) {
2413024130
match event {
24131-
multi_buffer::Event::Edited { edited_buffer } => {
24131+
multi_buffer::Event::Edited {
24132+
edited_buffer,
24133+
is_local,
24134+
} => {
2413224135
self.scrollbar_marker_state.dirty = true;
2413324136
self.active_indent_guides_state.dirty = true;
2413424137
self.refresh_active_diagnostics(cx);
@@ -24138,7 +24141,7 @@ impl Editor {
2413824141
self.refresh_matching_bracket_highlights(&snapshot, cx);
2413924142
self.refresh_outline_symbols_at_cursor(cx);
2414024143
self.refresh_sticky_headers(&snapshot, cx);
24141-
if self.has_active_edit_prediction() {
24144+
if *is_local && self.has_active_edit_prediction() {
2414224145
self.update_visible_edit_prediction(window, cx);
2414324146
}
2414424147

crates/git_ui/src/file_diff_view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ impl FileDiffView {
108108

109109
for buffer in [&old_buffer, &new_buffer] {
110110
cx.subscribe(buffer, move |this, _, event, _| match event {
111-
language::BufferEvent::Edited
111+
language::BufferEvent::Edited { .. }
112112
| language::BufferEvent::LanguageChanged(_)
113113
| language::BufferEvent::Reparsed => {
114114
this.buffer_changes_tx.send(()).ok();

crates/git_ui/src/text_diff_view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl TextDiffView {
165165
let (buffer_changes_tx, mut buffer_changes_rx) = watch::channel(());
166166

167167
cx.subscribe(&source_buffer, move |this, _, event, _| match event {
168-
language::BufferEvent::Edited
168+
language::BufferEvent::Edited { .. }
169169
| language::BufferEvent::LanguageChanged(_)
170170
| language::BufferEvent::Reparsed => {
171171
this.buffer_changes_tx.send(()).ok();

crates/language/src/buffer.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ pub enum BufferEvent {
359359
is_local: bool,
360360
},
361361
/// The buffer was edited.
362-
Edited,
362+
Edited { is_local: bool },
363363
/// The buffer's `dirty` bit changed.
364364
DirtyChanged,
365365
/// The buffer was saved.
@@ -2457,7 +2457,7 @@ impl Buffer {
24572457
false
24582458
};
24592459
if let Some((transaction_id, start_version)) = self.text.end_transaction_at(now) {
2460-
self.did_edit(&start_version, was_dirty, cx);
2460+
self.did_edit(&start_version, was_dirty, true, cx);
24612461
Some(transaction_id)
24622462
} else {
24632463
None
@@ -2844,15 +2844,21 @@ impl Buffer {
28442844
Some(edit_id)
28452845
}
28462846

2847-
fn did_edit(&mut self, old_version: &clock::Global, was_dirty: bool, cx: &mut Context<Self>) {
2847+
fn did_edit(
2848+
&mut self,
2849+
old_version: &clock::Global,
2850+
was_dirty: bool,
2851+
is_local: bool,
2852+
cx: &mut Context<Self>,
2853+
) {
28482854
self.was_changed();
28492855

28502856
if self.edits_since::<usize>(old_version).next().is_none() {
28512857
return;
28522858
}
28532859

28542860
self.reparse(cx, true);
2855-
cx.emit(BufferEvent::Edited);
2861+
cx.emit(BufferEvent::Edited { is_local });
28562862
if was_dirty != self.is_dirty() {
28572863
cx.emit(BufferEvent::DirtyChanged);
28582864
}
@@ -2964,7 +2970,7 @@ impl Buffer {
29642970
self.text.apply_ops(buffer_ops);
29652971
self.deferred_ops.insert(deferred_ops);
29662972
self.flush_deferred_ops(cx);
2967-
self.did_edit(&old_version, was_dirty, cx);
2973+
self.did_edit(&old_version, was_dirty, false, cx);
29682974
// Notify independently of whether the buffer was edited as the operations could include a
29692975
// selection update.
29702976
cx.notify();
@@ -3119,7 +3125,7 @@ impl Buffer {
31193125

31203126
if let Some((transaction_id, operation)) = self.text.undo() {
31213127
self.send_operation(Operation::Buffer(operation), true, cx);
3122-
self.did_edit(&old_version, was_dirty, cx);
3128+
self.did_edit(&old_version, was_dirty, true, cx);
31233129
self.restore_encoding_for_transaction(transaction_id, was_dirty);
31243130
Some(transaction_id)
31253131
} else {
@@ -3137,7 +3143,7 @@ impl Buffer {
31373143
let old_version = self.version.clone();
31383144
if let Some(operation) = self.text.undo_transaction(transaction_id) {
31393145
self.send_operation(Operation::Buffer(operation), true, cx);
3140-
self.did_edit(&old_version, was_dirty, cx);
3146+
self.did_edit(&old_version, was_dirty, true, cx);
31413147
true
31423148
} else {
31433149
false
@@ -3159,7 +3165,7 @@ impl Buffer {
31593165
self.send_operation(Operation::Buffer(operation), true, cx);
31603166
}
31613167
if undone {
3162-
self.did_edit(&old_version, was_dirty, cx)
3168+
self.did_edit(&old_version, was_dirty, true, cx)
31633169
}
31643170
undone
31653171
}
@@ -3169,7 +3175,7 @@ impl Buffer {
31693175
let operation = self.text.undo_operations(counts);
31703176
let old_version = self.version.clone();
31713177
self.send_operation(Operation::Buffer(operation), true, cx);
3172-
self.did_edit(&old_version, was_dirty, cx);
3178+
self.did_edit(&old_version, was_dirty, true, cx);
31733179
}
31743180

31753181
/// Manually redoes a specific transaction in the buffer's redo history.
@@ -3179,7 +3185,7 @@ impl Buffer {
31793185

31803186
if let Some((transaction_id, operation)) = self.text.redo() {
31813187
self.send_operation(Operation::Buffer(operation), true, cx);
3182-
self.did_edit(&old_version, was_dirty, cx);
3188+
self.did_edit(&old_version, was_dirty, true, cx);
31833189
self.restore_encoding_for_transaction(transaction_id, was_dirty);
31843190
Some(transaction_id)
31853191
} else {
@@ -3220,7 +3226,7 @@ impl Buffer {
32203226
self.send_operation(Operation::Buffer(operation), true, cx);
32213227
}
32223228
if redone {
3223-
self.did_edit(&old_version, was_dirty, cx)
3229+
self.did_edit(&old_version, was_dirty, true, cx)
32243230
}
32253231
redone
32263232
}
@@ -3330,7 +3336,7 @@ impl Buffer {
33303336
if !ops.is_empty() {
33313337
for op in ops {
33323338
self.send_operation(Operation::Buffer(op), true, cx);
3333-
self.did_edit(&old_version, was_dirty, cx);
3339+
self.did_edit(&old_version, was_dirty, true, cx);
33343340
}
33353341
}
33363342
}

crates/language/src/buffer_tests.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,18 @@ fn test_edit_events(cx: &mut gpui::App) {
458458
assert_eq!(
459459
mem::take(&mut *buffer_1_events.lock()),
460460
vec![
461-
BufferEvent::Edited,
461+
BufferEvent::Edited { is_local: true },
462462
BufferEvent::DirtyChanged,
463-
BufferEvent::Edited,
464-
BufferEvent::Edited,
463+
BufferEvent::Edited { is_local: true },
464+
BufferEvent::Edited { is_local: true },
465465
]
466466
);
467467
assert_eq!(
468468
mem::take(&mut *buffer_2_events.lock()),
469-
vec![BufferEvent::Edited, BufferEvent::DirtyChanged]
469+
vec![
470+
BufferEvent::Edited { is_local: false },
471+
BufferEvent::DirtyChanged
472+
]
470473
);
471474

472475
buffer1.update(cx, |buffer, cx| {
@@ -481,11 +484,17 @@ fn test_edit_events(cx: &mut gpui::App) {
481484
});
482485
assert_eq!(
483486
mem::take(&mut *buffer_1_events.lock()),
484-
vec![BufferEvent::Edited, BufferEvent::DirtyChanged,]
487+
vec![
488+
BufferEvent::Edited { is_local: true },
489+
BufferEvent::DirtyChanged,
490+
]
485491
);
486492
assert_eq!(
487493
mem::take(&mut *buffer_2_events.lock()),
488-
vec![BufferEvent::Edited, BufferEvent::DirtyChanged]
494+
vec![
495+
BufferEvent::Edited { is_local: false },
496+
BufferEvent::DirtyChanged
497+
]
489498
);
490499
}
491500

0 commit comments

Comments
 (0)