Capture a new buffer snapshot for excerpts whose selections got updated

Antonio Scandurra created

Change summary

crates/editor/src/multi_buffer.rs | 12 +++++++++++-
crates/language/src/buffer.rs     | 19 ++++++++++++++++---
2 files changed, 27 insertions(+), 4 deletions(-)

Detailed changes

crates/editor/src/multi_buffer.rs 🔗

@@ -68,6 +68,7 @@ struct BufferState {
     buffer: ModelHandle<Buffer>,
     last_version: clock::Global,
     last_parse_count: usize,
+    last_selections_update_count: usize,
     last_diagnostics_update_count: usize,
     excerpts: Vec<ExcerptId>,
     _subscriptions: [gpui::Subscription; 2],
@@ -637,6 +638,7 @@ impl MultiBuffer {
             .or_insert_with(|| BufferState {
                 last_version: buffer_snapshot.version().clone(),
                 last_parse_count: buffer_snapshot.parse_count(),
+                last_selections_update_count: buffer_snapshot.selections_update_count(),
                 last_diagnostics_update_count: buffer_snapshot.diagnostics_update_count(),
                 excerpts: Default::default(),
                 _subscriptions: [
@@ -799,15 +801,23 @@ impl MultiBuffer {
             let buffer = buffer_state.buffer.read(cx);
             let version = buffer.version();
             let parse_count = buffer.parse_count();
+            let selections_update_count = buffer.selections_update_count();
             let diagnostics_update_count = buffer.diagnostics_update_count();
 
             let buffer_edited = version.gt(&buffer_state.last_version);
             let buffer_reparsed = parse_count > buffer_state.last_parse_count;
+            let buffer_selections_updated =
+                selections_update_count > buffer_state.last_selections_update_count;
             let buffer_diagnostics_updated =
                 diagnostics_update_count > buffer_state.last_diagnostics_update_count;
-            if buffer_edited || buffer_reparsed || buffer_diagnostics_updated {
+            if buffer_edited
+                || buffer_reparsed
+                || buffer_selections_updated
+                || buffer_diagnostics_updated
+            {
                 buffer_state.last_version = version;
                 buffer_state.last_parse_count = parse_count;
+                buffer_state.last_selections_update_count = selections_update_count;
                 buffer_state.last_diagnostics_update_count = diagnostics_update_count;
                 excerpts_to_edit.extend(
                     buffer_state

crates/language/src/buffer.rs 🔗

@@ -66,6 +66,7 @@ pub struct Buffer {
     parsing_in_background: bool,
     parse_count: usize,
     remote_selections: TreeMap<ReplicaId, Arc<[Selection<Anchor>]>>,
+    selections_update_count: usize,
     diagnostic_sets: Vec<DiagnosticSet>,
     diagnostics_update_count: usize,
     language_server: Option<LanguageServerState>,
@@ -78,8 +79,9 @@ pub struct BufferSnapshot {
     text: text::BufferSnapshot,
     tree: Option<Tree>,
     diagnostic_sets: Vec<DiagnosticSet>,
-    remote_selections: TreeMap<ReplicaId, Arc<[Selection<Anchor>]>>,
     diagnostics_update_count: usize,
+    remote_selections: TreeMap<ReplicaId, Arc<[Selection<Anchor>]>>,
+    selections_update_count: usize,
     is_parsing: bool,
     language: Option<Arc<Language>>,
     parse_count: usize,
@@ -373,6 +375,7 @@ impl Buffer {
             pending_autoindent: Default::default(),
             language: None,
             remote_selections: Default::default(),
+            selections_update_count: 0,
             diagnostic_sets: Default::default(),
             diagnostics_update_count: 0,
             language_server: None,
@@ -392,6 +395,7 @@ impl Buffer {
             is_parsing: self.parsing_in_background,
             language: self.language.clone(),
             parse_count: self.parse_count,
+            selections_update_count: self.selections_update_count,
         }
     }
 
@@ -617,6 +621,10 @@ impl Buffer {
         self.parse_count
     }
 
+    pub fn selections_update_count(&self) -> usize {
+        self.selections_update_count
+    }
+
     pub fn diagnostics_update_count(&self) -> usize {
         self.diagnostics_update_count
     }
@@ -1088,8 +1096,6 @@ impl Buffer {
         cx: &mut ModelContext<Self>,
     ) {
         let lamport_timestamp = self.text.lamport_clock.tick();
-        self.remote_selections
-            .insert(self.text.replica_id(), selections.clone());
         self.send_operation(
             Operation::UpdateSelections {
                 replica_id: self.text.replica_id(),
@@ -1362,6 +1368,7 @@ impl Buffer {
             } => {
                 self.remote_selections.insert(replica_id, selections);
                 self.text.lamport_clock.observe(lamport_timestamp);
+                self.selections_update_count += 1;
             }
             Operation::RemoveSelections {
                 replica_id,
@@ -1369,6 +1376,7 @@ impl Buffer {
             } => {
                 self.remote_selections.remove(&replica_id);
                 self.text.lamport_clock.observe(lamport_timestamp);
+                self.selections_update_count += 1;
             }
         }
     }
@@ -1791,6 +1799,10 @@ impl BufferSnapshot {
     pub fn parse_count(&self) -> usize {
         self.parse_count
     }
+
+    pub fn selections_update_count(&self) -> usize {
+        self.selections_update_count
+    }
 }
 
 impl Clone for BufferSnapshot {
@@ -1799,6 +1811,7 @@ impl Clone for BufferSnapshot {
             text: self.text.clone(),
             tree: self.tree.clone(),
             remote_selections: self.remote_selections.clone(),
+            selections_update_count: self.selections_update_count,
             diagnostic_sets: self.diagnostic_sets.clone(),
             diagnostics_update_count: self.diagnostics_update_count,
             is_parsing: self.is_parsing,