From 7ae1d9e997f76c2054c951f716c2418c20102e65 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 2 Jul 2021 11:29:36 +0200 Subject: [PATCH] Send also the currently active selection sets when serializing a buffer --- zed-rpc/proto/zed.proto | 8 ++++ zed/src/editor/buffer.rs | 91 ++++++++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 26 deletions(-) diff --git a/zed-rpc/proto/zed.proto b/zed-rpc/proto/zed.proto index da2a2f40e97c527f5e67a8196987b049c88df4ed..480fa6fdfdbb877f218d2f139bc9259270e83edb 100644 --- a/zed-rpc/proto/zed.proto +++ b/zed-rpc/proto/zed.proto @@ -115,6 +115,14 @@ message Buffer { uint64 id = 1; string content = 2; repeated Operation.Edit history = 3; + repeated SelectionSetSnapshot selections = 4; +} + +message SelectionSetSnapshot { + uint32 replica_id = 1; + uint32 local_timestamp = 2; + repeated Selection selections = 3; + bool is_active = 4; } message SelectionSet { diff --git a/zed/src/editor/buffer.rs b/zed/src/editor/buffer.rs index 210c091ec8d17c89ec701eac2d5f9848599ed0e0..84fc11069f16f3473ffa131e1cf23c1f9ac12f91 100644 --- a/zed/src/editor/buffer.rs +++ b/zed/src/editor/buffer.rs @@ -616,6 +616,26 @@ impl Buffer { .into_iter() .map(|op| Operation::Edit(op.into())); buffer.apply_ops(ops, cx)?; + buffer.selections = message + .selections + .into_iter() + .map(|set| { + let set_id = time::Lamport { + replica_id: set.replica_id as ReplicaId, + value: set.local_timestamp, + }; + let selections: Vec = set + .selections + .into_iter() + .map(TryFrom::try_from) + .collect::>()?; + let set = SelectionSet { + selections: Arc::from(selections), + active: set.is_active, + }; + Result::<_, anyhow::Error>::Ok((set_id, set)) + }) + .collect::>()?; Ok(buffer) } @@ -625,6 +645,16 @@ impl Buffer { id: cx.model_id() as u64, content: self.history.base_text.to_string(), history: ops, + selections: self + .selections + .iter() + .map(|(set_id, set)| proto::SelectionSetSnapshot { + replica_id: set_id.replica_id as u32, + local_timestamp: set_id.value, + selections: set.selections.iter().map(Into::into).collect(), + is_active: set.active, + }) + .collect(), } } @@ -2428,15 +2458,7 @@ impl<'a> Into for &'a Operation { local_timestamp: set_id.value, lamport_timestamp: lamport_timestamp.value, set: selections.as_ref().map(|selections| proto::SelectionSet { - selections: selections - .iter() - .map(|selection| proto::Selection { - id: selection.id as u64, - start: Some((&selection.start).into()), - end: Some((&selection.end).into()), - reversed: selection.reversed, - }) - .collect(), + selections: selections.iter().map(Into::into).collect(), }), }, ), @@ -2496,6 +2518,17 @@ impl<'a> Into for &'a Anchor { } } +impl<'a> Into for &'a Selection { + fn into(self) -> proto::Selection { + proto::Selection { + id: self.id as u64, + start: Some((&self.start).into()), + end: Some((&self.end).into()), + reversed: self.reversed, + } + } +} + impl TryFrom for Operation { type Error = anyhow::Error; @@ -2538,26 +2571,12 @@ impl TryFrom for Operation { }, }, proto::operation::Variant::UpdateSelections(message) => { - let selections = if let Some(set) = message.set { + let selections: Option> = if let Some(set) = message.set { Some( set.selections .into_iter() - .map(|selection| { - Ok(Selection { - id: selection.id as usize, - start: selection - .start - .ok_or_else(|| anyhow!("missing selection start"))? - .try_into()?, - end: selection - .end - .ok_or_else(|| anyhow!("missing selection end"))? - .try_into()?, - reversed: selection.reversed, - goal: SelectionGoal::None, - }) - }) - .collect::, anyhow::Error>>()?, + .map(TryFrom::try_from) + .collect::>()?, ) } else { None @@ -2637,6 +2656,26 @@ impl TryFrom for Anchor { } } +impl TryFrom for Selection { + type Error = anyhow::Error; + + fn try_from(selection: proto::Selection) -> Result { + Ok(Selection { + id: selection.id as usize, + start: selection + .start + .ok_or_else(|| anyhow!("missing selection start"))? + .try_into()?, + end: selection + .end + .ok_or_else(|| anyhow!("missing selection end"))? + .try_into()?, + reversed: selection.reversed, + goal: SelectionGoal::None, + }) + } +} + impl operation_queue::Operation for Operation { fn timestamp(&self) -> time::Lamport { self.lamport_timestamp()