diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index c18a127a3e..3b0286b549 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -287,12 +287,12 @@ impl Buffer { file: Option>, cx: &mut ModelContext, ) -> Result { - let mut fragments_len = message.fragments.len(); + let fragments_len = message.fragments.len(); let buffer = TextBuffer::from_parts( replica_id, message.id, - message.content, - message.deleted_content, + &message.visible_text, + &message.deleted_text, message .undo_map .into_iter() @@ -304,6 +304,8 @@ impl Buffer { .map(|(i, fragment)| { proto::deserialize_buffer_fragment(fragment, i, fragments_len) }), + message.lamport_timestamp, + From::from(message.version), ); let mut this = Self::build(buffer, file); for selection_set in message.selections { @@ -331,14 +333,15 @@ impl Buffer { pub fn to_proto(&self) -> proto::Buffer { proto::Buffer { id: self.remote_id(), - content: self.text.text(), - deleted_content: self.text.deleted_text(), + visible_text: self.text.text(), + deleted_text: self.text.deleted_text(), undo_map: self .text .undo_history() .map(proto::serialize_undo_map_entry) .collect(), - version: proto::serialize_vector_clock(&self.version), + version: From::from(&self.version), + lamport_timestamp: self.lamport_clock.value, fragments: self .text .fragments() @@ -1114,6 +1117,8 @@ impl Buffer { cx: &mut ModelContext, ) { 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(), diff --git a/crates/language/src/proto.rs b/crates/language/src/proto.rs index 9c7a89cc01..4898a7ccd4 100644 --- a/crates/language/src/proto.rs +++ b/crates/language/src/proto.rs @@ -1,6 +1,7 @@ use crate::{diagnostic_set::DiagnosticEntry, Diagnostic, Operation}; use anyhow::{anyhow, Result}; use clock::ReplicaId; +use collections::HashSet; use lsp::DiagnosticSeverity; use rpc::proto; use std::sync::Arc; @@ -124,14 +125,7 @@ pub fn serialize_buffer_fragment(fragment: &text::Fragment) -> proto::BufferFrag timestamp: clock.value, }) .collect(), - max_undos: fragment - .max_undos - .iter() - .map(|clock| proto::VectorClockEntry { - replica_id: clock.replica_id as u32, - timestamp: clock.value, - }) - .collect(), + max_undos: From::from(&fragment.max_undos), } } @@ -325,7 +319,22 @@ pub fn deserialize_buffer_fragment( ix: usize, count: usize, ) -> Fragment { - todo!() + Fragment { + id: locator::Locator::from_index(ix, count), + insertion_timestamp: InsertionTimestamp { + replica_id: message.replica_id as ReplicaId, + local: message.local_timestamp, + lamport: message.lamport_timestamp, + }, + insertion_offset: message.insertion_offset as usize, + len: message.len as usize, + visible: message.visible, + deletions: HashSet::from_iter(message.deletions.into_iter().map(|entry| clock::Local { + replica_id: entry.replica_id as ReplicaId, + value: entry.timestamp, + })), + max_undos: From::from(message.max_undos), + } } pub fn deserialize_selections(selections: Vec) -> Arc<[Selection]> { diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 78eccdefa0..6e2e30a10d 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -262,13 +262,14 @@ message Entry { message Buffer { uint64 id = 1; - string content = 2; - string deleted_content = 3; + string visible_text = 2; + string deleted_text = 3; repeated BufferFragment fragments = 4; repeated UndoMapEntry undo_map = 5; repeated VectorClockEntry version = 6; repeated SelectionSet selections = 7; repeated DiagnosticSet diagnostic_sets = 8; + uint32 lamport_timestamp = 9; } message BufferFragment { diff --git a/crates/rpc/src/peer.rs b/crates/rpc/src/peer.rs index 9b6d8c8786..091a0c1555 100644 --- a/crates/rpc/src/peer.rs +++ b/crates/rpc/src/peer.rs @@ -398,7 +398,7 @@ mod tests { proto::OpenBufferResponse { buffer: Some(proto::Buffer { id: 101, - content: "path/one content".to_string(), + visible_text: "path/one content".to_string(), ..Default::default() }), } @@ -419,7 +419,7 @@ mod tests { proto::OpenBufferResponse { buffer: Some(proto::Buffer { id: 102, - content: "path/two content".to_string(), + visible_text: "path/two content".to_string(), ..Default::default() }), } @@ -448,7 +448,7 @@ mod tests { proto::OpenBufferResponse { buffer: Some(proto::Buffer { id: 101, - content: "path/one content".to_string(), + visible_text: "path/one content".to_string(), ..Default::default() }), } @@ -458,7 +458,7 @@ mod tests { proto::OpenBufferResponse { buffer: Some(proto::Buffer { id: 102, - content: "path/two content".to_string(), + visible_text: "path/two content".to_string(), ..Default::default() }), } diff --git a/crates/text/src/locator.rs b/crates/text/src/locator.rs index e4feaf99ac..ddd3663e73 100644 --- a/crates/text/src/locator.rs +++ b/crates/text/src/locator.rs @@ -19,6 +19,11 @@ impl Locator { Self(smallvec![u64::MAX]) } + pub fn from_index(ix: usize, count: usize) -> Self { + let id = ((ix as u128 * u64::MAX as u128) / count as u128) as u64; + Self(smallvec![id]) + } + pub fn assign(&mut self, other: &Self) { self.0.resize(other.0.len(), 0); self.0.copy_from_slice(&other.0); diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 6b35d25a79..692bd304ce 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -42,7 +42,6 @@ pub type TransactionId = usize; pub struct Buffer { snapshot: BufferSnapshot, - last_edit: clock::Local, history: History, deferred_ops: OperationQueue, deferred_replicas: HashSet, @@ -385,7 +384,7 @@ impl InsertionTimestamp { #[derive(Eq, PartialEq, Clone, Debug)] pub struct Fragment { - id: Locator, + pub id: Locator, pub insertion_timestamp: InsertionTimestamp, pub insertion_offset: usize, pub len: usize, @@ -496,7 +495,6 @@ impl Buffer { version, undo_map: Default::default(), }, - last_edit: clock::Local::default(), history, deferred_ops: OperationQueue::new(), deferred_replicas: HashSet::default(), @@ -515,30 +513,46 @@ impl Buffer { deleted_text: &str, undo_map: impl Iterator)>, fragments: impl ExactSizeIterator, + lamport_timestamp: u32, + version: clock::Global, ) -> Self { let visible_text = visible_text.into(); let deleted_text = deleted_text.into(); let fragments = SumTree::from_iter(fragments, &None); - let undo_map = UndoMap(undo_map.collect()); + let mut insertions = fragments + .iter() + .map(|fragment| InsertionFragment { + timestamp: fragment.insertion_timestamp.local(), + split_offset: fragment.insertion_offset, + fragment_id: fragment.id.clone(), + }) + .collect::>(); + insertions.sort_unstable_by_key(|i| (i.timestamp, i.split_offset)); Self { remote_id, replica_id, + + history: History::new("".into()), + deferred_ops: OperationQueue::new(), + deferred_replicas: Default::default(), + local_clock: clock::Local { + replica_id, + value: version.get(replica_id) + 1, + }, + lamport_clock: clock::Lamport { + replica_id, + value: lamport_timestamp, + }, + subscriptions: Default::default(), snapshot: BufferSnapshot { replica_id, visible_text, deleted_text, - undo_map, + undo_map: UndoMap(undo_map.collect()), fragments, - insertions: (), - version: (), + insertions: SumTree::from_iter(insertions, &()), + version, }, - history: History::new("".into()), - deferred_ops: OperationQueue::new(), - deferred_replicas: Default::default(), - last_edit: todo!(), - local_clock: todo!(), - lamport_clock: todo!(), - subscriptions: Default::default(), } } @@ -591,7 +605,6 @@ impl Buffer { self.history.push(edit.clone()); self.history.push_undo(edit.timestamp.local()); - self.last_edit = edit.timestamp.local(); self.snapshot.version.observe(edit.timestamp.local()); self.end_transaction(); edit @@ -1338,16 +1351,7 @@ impl BufferSnapshot { } pub fn fragments(&self) -> impl Iterator { - let mut cursor = self.fragments.cursor::<()>(); - let mut started = false; - std::iter::from_fn(move || { - if started { - cursor.next(&None); - } else { - started = true; - } - cursor.item() - }) + self.fragments.iter() } pub fn text_summary(&self) -> TextSummary {