Send full multibuffer anchors to following peers
This commit is contained in:
parent
3eac3e20d5
commit
6d9b55a654
4 changed files with 73 additions and 74 deletions
|
@ -65,34 +65,26 @@ impl FollowableItem for Editor {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
editor.update(&mut cx, |editor, cx| {
|
editor.update(&mut cx, |editor, cx| {
|
||||||
let excerpt_id;
|
|
||||||
let buffer_id;
|
|
||||||
{
|
|
||||||
let buffer = editor.buffer.read(cx).read(cx);
|
let buffer = editor.buffer.read(cx).read(cx);
|
||||||
let singleton = buffer.as_singleton().unwrap();
|
|
||||||
excerpt_id = singleton.0.clone();
|
|
||||||
buffer_id = singleton.1;
|
|
||||||
}
|
|
||||||
let selections = state
|
let selections = state
|
||||||
.selections
|
.selections
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| {
|
.map(|selection| {
|
||||||
deserialize_selection(&excerpt_id, buffer_id, selection)
|
deserialize_selection(&buffer, selection)
|
||||||
.ok_or_else(|| anyhow!("invalid selection"))
|
.ok_or_else(|| anyhow!("invalid selection"))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
let scroll_top_anchor = state
|
||||||
|
.scroll_top_anchor
|
||||||
|
.and_then(|anchor| deserialize_anchor(&buffer, anchor));
|
||||||
|
drop(buffer);
|
||||||
|
|
||||||
if !selections.is_empty() {
|
if !selections.is_empty() {
|
||||||
editor.set_selections_from_remote(selections, cx);
|
editor.set_selections_from_remote(selections, cx);
|
||||||
}
|
}
|
||||||
|
if let Some(scroll_top_anchor) = scroll_top_anchor {
|
||||||
if let Some(anchor) = state.scroll_top_anchor {
|
|
||||||
editor.set_scroll_top_anchor(
|
editor.set_scroll_top_anchor(
|
||||||
Anchor {
|
scroll_top_anchor,
|
||||||
buffer_id: Some(state.buffer_id as usize),
|
|
||||||
excerpt_id,
|
|
||||||
text_anchor: language::proto::deserialize_anchor(anchor)
|
|
||||||
.ok_or_else(|| anyhow!("invalid scroll top"))?,
|
|
||||||
},
|
|
||||||
vec2f(state.scroll_x, state.scroll_y),
|
vec2f(state.scroll_x, state.scroll_y),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -133,9 +125,7 @@ impl FollowableItem for Editor {
|
||||||
let buffer_id = self.buffer.read(cx).as_singleton()?.read(cx).remote_id();
|
let buffer_id = self.buffer.read(cx).as_singleton()?.read(cx).remote_id();
|
||||||
Some(proto::view::Variant::Editor(proto::view::Editor {
|
Some(proto::view::Variant::Editor(proto::view::Editor {
|
||||||
buffer_id,
|
buffer_id,
|
||||||
scroll_top_anchor: Some(language::proto::serialize_anchor(
|
scroll_top_anchor: Some(serialize_anchor(&self.scroll_top_anchor)),
|
||||||
&self.scroll_top_anchor.text_anchor,
|
|
||||||
)),
|
|
||||||
scroll_x: self.scroll_position.x(),
|
scroll_x: self.scroll_position.x(),
|
||||||
scroll_y: self.scroll_position.y(),
|
scroll_y: self.scroll_position.y(),
|
||||||
selections: self
|
selections: self
|
||||||
|
@ -159,9 +149,7 @@ impl FollowableItem for Editor {
|
||||||
match update {
|
match update {
|
||||||
proto::update_view::Variant::Editor(update) => match event {
|
proto::update_view::Variant::Editor(update) => match event {
|
||||||
Event::ScrollPositionChanged { .. } => {
|
Event::ScrollPositionChanged { .. } => {
|
||||||
update.scroll_top_anchor = Some(language::proto::serialize_anchor(
|
update.scroll_top_anchor = Some(serialize_anchor(&self.scroll_top_anchor));
|
||||||
&self.scroll_top_anchor.text_anchor,
|
|
||||||
));
|
|
||||||
update.scroll_x = self.scroll_position.x();
|
update.scroll_x = self.scroll_position.x();
|
||||||
update.scroll_y = self.scroll_position.y();
|
update.scroll_y = self.scroll_position.y();
|
||||||
true
|
true
|
||||||
|
@ -190,29 +178,22 @@ impl FollowableItem for Editor {
|
||||||
update_view::Variant::Editor(message) => {
|
update_view::Variant::Editor(message) => {
|
||||||
let buffer = self.buffer.read(cx);
|
let buffer = self.buffer.read(cx);
|
||||||
let buffer = buffer.read(cx);
|
let buffer = buffer.read(cx);
|
||||||
let (excerpt_id, buffer_id, _) = buffer.as_singleton().unwrap();
|
|
||||||
let excerpt_id = excerpt_id.clone();
|
|
||||||
drop(buffer);
|
|
||||||
|
|
||||||
let selections = message
|
let selections = message
|
||||||
.selections
|
.selections
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|selection| {
|
.filter_map(|selection| deserialize_selection(&buffer, selection))
|
||||||
deserialize_selection(&excerpt_id, buffer_id, selection)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
let scroll_top_anchor = message
|
||||||
|
.scroll_top_anchor
|
||||||
|
.and_then(|anchor| deserialize_anchor(&buffer, anchor));
|
||||||
|
drop(buffer);
|
||||||
|
|
||||||
if !selections.is_empty() {
|
if !selections.is_empty() {
|
||||||
self.set_selections_from_remote(selections, cx);
|
self.set_selections_from_remote(selections, cx);
|
||||||
self.request_autoscroll_remotely(Autoscroll::newest(), cx);
|
self.request_autoscroll_remotely(Autoscroll::newest(), cx);
|
||||||
} else if let Some(anchor) = message.scroll_top_anchor {
|
} else if let Some(anchor) = scroll_top_anchor {
|
||||||
self.set_scroll_top_anchor(
|
self.set_scroll_top_anchor(
|
||||||
Anchor {
|
anchor,
|
||||||
buffer_id: Some(buffer_id),
|
|
||||||
excerpt_id,
|
|
||||||
text_anchor: language::proto::deserialize_anchor(anchor)
|
|
||||||
.ok_or_else(|| anyhow!("invalid scroll top"))?,
|
|
||||||
},
|
|
||||||
vec2f(message.scroll_x, message.scroll_y),
|
vec2f(message.scroll_x, message.scroll_y),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -235,38 +216,41 @@ impl FollowableItem for Editor {
|
||||||
fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection {
|
fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection {
|
||||||
proto::Selection {
|
proto::Selection {
|
||||||
id: selection.id as u64,
|
id: selection.id as u64,
|
||||||
start: Some(language::proto::serialize_anchor(
|
start: Some(serialize_anchor(&selection.start)),
|
||||||
&selection.start.text_anchor,
|
end: Some(serialize_anchor(&selection.end)),
|
||||||
)),
|
|
||||||
end: Some(language::proto::serialize_anchor(
|
|
||||||
&selection.end.text_anchor,
|
|
||||||
)),
|
|
||||||
reversed: selection.reversed,
|
reversed: selection.reversed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize_anchor(anchor: &Anchor) -> proto::EditorAnchor {
|
||||||
|
proto::EditorAnchor {
|
||||||
|
excerpt_id: anchor.excerpt_id.to_proto(),
|
||||||
|
anchor: Some(language::proto::serialize_anchor(&anchor.text_anchor)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn deserialize_selection(
|
fn deserialize_selection(
|
||||||
excerpt_id: &ExcerptId,
|
buffer: &MultiBufferSnapshot,
|
||||||
buffer_id: usize,
|
|
||||||
selection: proto::Selection,
|
selection: proto::Selection,
|
||||||
) -> Option<Selection<Anchor>> {
|
) -> Option<Selection<Anchor>> {
|
||||||
Some(Selection {
|
Some(Selection {
|
||||||
id: selection.id as usize,
|
id: selection.id as usize,
|
||||||
start: Anchor {
|
start: deserialize_anchor(buffer, selection.start?)?,
|
||||||
buffer_id: Some(buffer_id),
|
end: deserialize_anchor(buffer, selection.end?)?,
|
||||||
excerpt_id: excerpt_id.clone(),
|
|
||||||
text_anchor: language::proto::deserialize_anchor(selection.start?)?,
|
|
||||||
},
|
|
||||||
end: Anchor {
|
|
||||||
buffer_id: Some(buffer_id),
|
|
||||||
excerpt_id: excerpt_id.clone(),
|
|
||||||
text_anchor: language::proto::deserialize_anchor(selection.end?)?,
|
|
||||||
},
|
|
||||||
reversed: selection.reversed,
|
reversed: selection.reversed,
|
||||||
goal: SelectionGoal::None,
|
goal: SelectionGoal::None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_anchor(buffer: &MultiBufferSnapshot, anchor: proto::EditorAnchor) -> Option<Anchor> {
|
||||||
|
let excerpt_id = ExcerptId::from_proto(anchor.excerpt_id);
|
||||||
|
Some(Anchor {
|
||||||
|
excerpt_id,
|
||||||
|
text_anchor: language::proto::deserialize_anchor(anchor.anchor?)?,
|
||||||
|
buffer_id: Some(buffer.buffer_id_for_excerpt(excerpt_id)?),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
impl Item for Editor {
|
impl Item for Editor {
|
||||||
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) -> bool {
|
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) -> bool {
|
||||||
if let Ok(data) = data.downcast::<NavigationData>() {
|
if let Ok(data) = data.downcast::<NavigationData>() {
|
||||||
|
|
|
@ -2813,6 +2813,10 @@ impl MultiBufferSnapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn buffer_id_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<usize> {
|
||||||
|
Some(self.excerpt(excerpt_id)?.buffer_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn excerpt<'a>(&'a self, excerpt_id: ExcerptId) -> Option<&'a Excerpt> {
|
fn excerpt<'a>(&'a self, excerpt_id: ExcerptId) -> Option<&'a Excerpt> {
|
||||||
let mut cursor = self.excerpts.cursor::<Option<&Locator>>();
|
let mut cursor = self.excerpts.cursor::<Option<&Locator>>();
|
||||||
let locator = self.excerpt_locator_for_id(excerpt_id);
|
let locator = self.excerpt_locator_for_id(excerpt_id);
|
||||||
|
@ -3147,6 +3151,14 @@ impl ExcerptId {
|
||||||
Self(usize::MAX)
|
Self(usize::MAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_proto(&self) -> u64 {
|
||||||
|
self.0 as _
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_proto(proto: u64) -> Self {
|
||||||
|
Self(proto as _)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cmp(&self, other: &Self, snapshot: &MultiBufferSnapshot) -> cmp::Ordering {
|
pub fn cmp(&self, other: &Self, snapshot: &MultiBufferSnapshot) -> cmp::Ordering {
|
||||||
let a = snapshot.excerpt_locator_for_id(*self);
|
let a = snapshot.excerpt_locator_for_id(*self);
|
||||||
let b = snapshot.excerpt_locator_for_id(*other);
|
let b = snapshot.excerpt_locator_for_id(*other);
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rpc::proto;
|
||||||
use std::{ops::Range, sync::Arc};
|
use std::{ops::Range, sync::Arc};
|
||||||
use text::*;
|
use text::*;
|
||||||
|
|
||||||
pub use proto::{BufferState, Operation, SelectionSet};
|
pub use proto::{BufferState, Operation};
|
||||||
|
|
||||||
pub fn deserialize_line_ending(message: proto::LineEnding) -> fs::LineEnding {
|
pub fn deserialize_line_ending(message: proto::LineEnding) -> fs::LineEnding {
|
||||||
match message {
|
match message {
|
||||||
|
@ -122,8 +122,14 @@ pub fn serialize_selections(selections: &Arc<[Selection<Anchor>]>) -> Vec<proto:
|
||||||
pub fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection {
|
pub fn serialize_selection(selection: &Selection<Anchor>) -> proto::Selection {
|
||||||
proto::Selection {
|
proto::Selection {
|
||||||
id: selection.id as u64,
|
id: selection.id as u64,
|
||||||
start: Some(serialize_anchor(&selection.start)),
|
start: Some(proto::EditorAnchor {
|
||||||
end: Some(serialize_anchor(&selection.end)),
|
anchor: Some(serialize_anchor(&selection.start)),
|
||||||
|
excerpt_id: 0,
|
||||||
|
}),
|
||||||
|
end: Some(proto::EditorAnchor {
|
||||||
|
anchor: Some(serialize_anchor(&selection.end)),
|
||||||
|
excerpt_id: 0,
|
||||||
|
}),
|
||||||
reversed: selection.reversed,
|
reversed: selection.reversed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,8 +235,8 @@ pub fn deserialize_operation(message: proto::Operation) -> Result<crate::Operati
|
||||||
.filter_map(|selection| {
|
.filter_map(|selection| {
|
||||||
Some(Selection {
|
Some(Selection {
|
||||||
id: selection.id as usize,
|
id: selection.id as usize,
|
||||||
start: deserialize_anchor(selection.start?)?,
|
start: deserialize_anchor(selection.start?.anchor?)?,
|
||||||
end: deserialize_anchor(selection.end?)?,
|
end: deserialize_anchor(selection.end?.anchor?)?,
|
||||||
reversed: selection.reversed,
|
reversed: selection.reversed,
|
||||||
goal: SelectionGoal::None,
|
goal: SelectionGoal::None,
|
||||||
})
|
})
|
||||||
|
@ -321,8 +327,8 @@ pub fn deserialize_selections(selections: Vec<proto::Selection>) -> Arc<[Selecti
|
||||||
pub fn deserialize_selection(selection: proto::Selection) -> Option<Selection<Anchor>> {
|
pub fn deserialize_selection(selection: proto::Selection) -> Option<Selection<Anchor>> {
|
||||||
Some(Selection {
|
Some(Selection {
|
||||||
id: selection.id as usize,
|
id: selection.id as usize,
|
||||||
start: deserialize_anchor(selection.start?)?,
|
start: deserialize_anchor(selection.start?.anchor?)?,
|
||||||
end: deserialize_anchor(selection.end?)?,
|
end: deserialize_anchor(selection.end?.anchor?)?,
|
||||||
reversed: selection.reversed,
|
reversed: selection.reversed,
|
||||||
goal: SelectionGoal::None,
|
goal: SelectionGoal::None,
|
||||||
})
|
})
|
||||||
|
|
|
@ -848,7 +848,7 @@ message UpdateView {
|
||||||
|
|
||||||
message Editor {
|
message Editor {
|
||||||
repeated Selection selections = 1;
|
repeated Selection selections = 1;
|
||||||
Anchor scroll_top_anchor = 2;
|
EditorAnchor scroll_top_anchor = 2;
|
||||||
float scroll_x = 3;
|
float scroll_x = 3;
|
||||||
float scroll_y = 4;
|
float scroll_y = 4;
|
||||||
}
|
}
|
||||||
|
@ -865,7 +865,7 @@ message View {
|
||||||
message Editor {
|
message Editor {
|
||||||
uint64 buffer_id = 1;
|
uint64 buffer_id = 1;
|
||||||
repeated Selection selections = 2;
|
repeated Selection selections = 2;
|
||||||
Anchor scroll_top_anchor = 3;
|
EditorAnchor scroll_top_anchor = 3;
|
||||||
float scroll_x = 4;
|
float scroll_x = 4;
|
||||||
float scroll_y = 5;
|
float scroll_y = 5;
|
||||||
}
|
}
|
||||||
|
@ -920,21 +920,18 @@ enum LineEnding {
|
||||||
Windows = 1;
|
Windows = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SelectionSet {
|
|
||||||
uint32 replica_id = 1;
|
|
||||||
repeated Selection selections = 2;
|
|
||||||
uint32 lamport_timestamp = 3;
|
|
||||||
bool line_mode = 4;
|
|
||||||
CursorShape cursor_shape = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Selection {
|
message Selection {
|
||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
Anchor start = 2;
|
EditorAnchor start = 2;
|
||||||
Anchor end = 3;
|
EditorAnchor end = 3;
|
||||||
bool reversed = 4;
|
bool reversed = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message EditorAnchor {
|
||||||
|
uint64 excerpt_id = 1;
|
||||||
|
Anchor anchor = 2;
|
||||||
|
}
|
||||||
|
|
||||||
enum CursorShape {
|
enum CursorShape {
|
||||||
CursorBar = 0;
|
CursorBar = 0;
|
||||||
CursorBlock = 1;
|
CursorBlock = 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue