mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Show remote collaborators' active selections
This commit is contained in:
parent
2adf11e204
commit
c984b39aaa
8 changed files with 117 additions and 45 deletions
|
@ -1991,8 +1991,8 @@ impl Editor {
|
|||
|
||||
pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext<Self>) {
|
||||
if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.undo(cx)) {
|
||||
if let Some((selections, _)) = self.selection_history.get(&tx_id) {
|
||||
self.selections = selections.clone();
|
||||
if let Some((selections, _)) = self.selection_history.get(&tx_id).cloned() {
|
||||
self.set_selections(selections, cx);
|
||||
}
|
||||
self.request_autoscroll(Autoscroll::Fit, cx);
|
||||
}
|
||||
|
@ -2000,8 +2000,8 @@ impl Editor {
|
|||
|
||||
pub fn redo(&mut self, _: &Redo, cx: &mut ViewContext<Self>) {
|
||||
if let Some(tx_id) = self.buffer.update(cx, |buffer, cx| buffer.redo(cx)) {
|
||||
if let Some((_, Some(selections))) = self.selection_history.get(&tx_id) {
|
||||
self.selections = selections.clone();
|
||||
if let Some((_, Some(selections))) = self.selection_history.get(&tx_id).cloned() {
|
||||
self.set_selections(selections, cx);
|
||||
}
|
||||
self.request_autoscroll(Autoscroll::Fit, cx);
|
||||
}
|
||||
|
@ -3256,13 +3256,23 @@ impl Editor {
|
|||
}
|
||||
self.pause_cursor_blinking(cx);
|
||||
|
||||
self.selections = Arc::from_iter(selections.into_iter().map(|selection| Selection {
|
||||
id: selection.id,
|
||||
start: buffer.anchor_before(selection.start),
|
||||
end: buffer.anchor_before(selection.end),
|
||||
reversed: selection.reversed,
|
||||
goal: selection.goal,
|
||||
}));
|
||||
self.set_selections(
|
||||
Arc::from_iter(selections.into_iter().map(|selection| Selection {
|
||||
id: selection.id,
|
||||
start: buffer.anchor_before(selection.start),
|
||||
end: buffer.anchor_before(selection.end),
|
||||
reversed: selection.reversed,
|
||||
goal: selection.goal,
|
||||
})),
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
fn set_selections(&mut self, selections: Arc<[Selection<Anchor>]>, cx: &mut ViewContext<Self>) {
|
||||
self.selections = selections;
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
buffer.set_active_selections(&self.selections, cx)
|
||||
});
|
||||
}
|
||||
|
||||
fn request_autoscroll(&mut self, autoscroll: Autoscroll, cx: &mut ViewContext<Self>) {
|
||||
|
@ -3651,11 +3661,16 @@ impl View for Editor {
|
|||
fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self.focused = true;
|
||||
self.blink_cursors(self.blink_epoch, cx);
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
buffer.set_active_selections(&self.selections, cx)
|
||||
});
|
||||
}
|
||||
|
||||
fn on_blur(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self.focused = false;
|
||||
self.show_local_cursors = false;
|
||||
self.buffer
|
||||
.update(cx, |buffer, cx| buffer.remove_active_selections(cx));
|
||||
cx.emit(Event::Blurred);
|
||||
cx.notify();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use language::{
|
|||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
cmp, io,
|
||||
iter::Peekable,
|
||||
iter::{FromIterator, Peekable},
|
||||
ops::{Range, Sub},
|
||||
sync::Arc,
|
||||
time::{Duration, Instant, SystemTime},
|
||||
|
@ -242,6 +242,34 @@ impl MultiBuffer {
|
|||
.update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
|
||||
}
|
||||
|
||||
pub fn set_active_selections(
|
||||
&mut self,
|
||||
selections: &[Selection<Anchor>],
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
// TODO
|
||||
let this = self.read(cx);
|
||||
self.as_singleton().unwrap().update(cx, |buffer, cx| {
|
||||
let buffer_snapshot = buffer.snapshot();
|
||||
let selections = selections.iter().map(|selection| Selection {
|
||||
id: selection.id,
|
||||
start: buffer_snapshot.anchor_before(selection.start.to_offset(&this)),
|
||||
end: buffer_snapshot.anchor_before(selection.end.to_offset(&this)),
|
||||
reversed: selection.reversed,
|
||||
goal: selection.goal,
|
||||
});
|
||||
buffer.set_active_selections(Arc::from_iter(selections), cx);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn remove_active_selections(&mut self, cx: &mut ModelContext<Self>) {
|
||||
for buffer in self.buffers.values() {
|
||||
buffer
|
||||
.buffer
|
||||
.update(cx, |buffer, cx| buffer.remove_active_selections(cx));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn undo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
|
||||
// TODO
|
||||
self.as_singleton()
|
||||
|
|
|
@ -289,6 +289,12 @@ impl Buffer {
|
|||
.map(|op| text::Operation::Edit(proto::deserialize_edit_operation(op)));
|
||||
buffer.apply_ops(ops)?;
|
||||
let mut this = Self::build(buffer, file);
|
||||
for selection_set in message.selections {
|
||||
this.remote_selections.insert(
|
||||
selection_set.replica_id as ReplicaId,
|
||||
proto::deserialize_selections(selection_set.selections),
|
||||
);
|
||||
}
|
||||
this.apply_diagnostic_update(
|
||||
Arc::from(proto::deserialize_diagnostics(message.diagnostics)),
|
||||
cx,
|
||||
|
@ -306,7 +312,14 @@ impl Buffer {
|
|||
.history()
|
||||
.map(proto::serialize_edit_operation)
|
||||
.collect(),
|
||||
selections: Vec::new(),
|
||||
selections: self
|
||||
.remote_selections
|
||||
.iter()
|
||||
.map(|(replica_id, selections)| proto::SelectionSet {
|
||||
replica_id: *replica_id as u32,
|
||||
selections: proto::serialize_selections(selections),
|
||||
})
|
||||
.collect(),
|
||||
diagnostics: proto::serialize_diagnostics(self.diagnostics.iter()),
|
||||
}
|
||||
}
|
||||
|
@ -835,7 +848,7 @@ impl Buffer {
|
|||
cx.emit(Event::DiagnosticsUpdated);
|
||||
Ok(Operation::UpdateDiagnostics {
|
||||
diagnostics: Arc::from(self.diagnostics.iter().cloned().collect::<Vec<_>>()),
|
||||
lamport_timestamp: self.lamport_timestamp(),
|
||||
lamport_timestamp: self.text.lamport_clock.tick(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1084,6 +1097,35 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_active_selections(
|
||||
&mut self,
|
||||
selections: Arc<[Selection<Anchor>]>,
|
||||
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(),
|
||||
selections,
|
||||
lamport_timestamp,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn remove_active_selections(&mut self, cx: &mut ModelContext<Self>) {
|
||||
let lamport_timestamp = self.text.lamport_clock.tick();
|
||||
self.send_operation(
|
||||
Operation::RemoveSelections {
|
||||
replica_id: self.text.replica_id(),
|
||||
lamport_timestamp,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
fn update_language_server(&mut self) {
|
||||
let language_server = if let Some(language_server) = self.language_server.as_mut() {
|
||||
language_server
|
||||
|
@ -1321,14 +1363,14 @@ impl Buffer {
|
|||
lamport_timestamp,
|
||||
} => {
|
||||
self.remote_selections.insert(replica_id, selections);
|
||||
self.text.observe_lamport_timestamp(lamport_timestamp);
|
||||
self.text.lamport_clock.observe(lamport_timestamp);
|
||||
}
|
||||
Operation::RemoveSelections {
|
||||
replica_id: set_id,
|
||||
replica_id,
|
||||
lamport_timestamp,
|
||||
} => {
|
||||
self.remote_selections.remove(&set_id);
|
||||
self.text.observe_lamport_timestamp(lamport_timestamp);
|
||||
self.remote_selections.remove(&replica_id);
|
||||
self.text.lamport_clock.observe(lamport_timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1655,6 +1697,7 @@ impl BufferSnapshot {
|
|||
{
|
||||
self.remote_selections
|
||||
.iter()
|
||||
.filter(|(replica_id, _)| **replica_id != self.text.replica_id())
|
||||
.map(move |(replica_id, selections)| {
|
||||
let start_ix = match selections
|
||||
.binary_search_by(|probe| probe.end.cmp(&range.start, self).unwrap())
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{diagnostic_set::DiagnosticEntry, Diagnostic, Operation};
|
||||
use anyhow::{anyhow, Result};
|
||||
use clock::ReplicaId;
|
||||
use lsp::DiagnosticSeverity;
|
||||
use rpc::proto;
|
||||
use std::sync::Arc;
|
||||
use text::*;
|
||||
|
||||
pub use proto::Buffer;
|
||||
pub use proto::{Buffer, SelectionSet};
|
||||
|
||||
pub fn serialize_operation(operation: &Operation) -> proto::Operation {
|
||||
proto::Operation {
|
||||
|
@ -48,15 +47,7 @@ pub fn serialize_operation(operation: &Operation) -> proto::Operation {
|
|||
} => proto::operation::Variant::UpdateSelections(proto::operation::UpdateSelections {
|
||||
replica_id: *replica_id as u32,
|
||||
lamport_timestamp: lamport_timestamp.value,
|
||||
selections: selections
|
||||
.iter()
|
||||
.map(|selection| proto::Selection {
|
||||
id: selection.id as u64,
|
||||
start: Some(serialize_anchor(&selection.start)),
|
||||
end: Some(serialize_anchor(&selection.end)),
|
||||
reversed: selection.reversed,
|
||||
})
|
||||
.collect(),
|
||||
selections: serialize_selections(selections),
|
||||
}),
|
||||
Operation::RemoveSelections {
|
||||
replica_id,
|
||||
|
|
|
@ -234,9 +234,7 @@ message Buffer {
|
|||
|
||||
message SelectionSet {
|
||||
uint32 replica_id = 1;
|
||||
uint32 lamport_timestamp = 2;
|
||||
bool is_active = 3;
|
||||
repeated Selection selections = 4;
|
||||
repeated Selection selections = 2;
|
||||
}
|
||||
|
||||
message Selection {
|
||||
|
|
|
@ -5,4 +5,4 @@ pub mod proto;
|
|||
pub use conn::Connection;
|
||||
pub use peer::*;
|
||||
|
||||
pub const PROTOCOL_VERSION: u32 = 3;
|
||||
pub const PROTOCOL_VERSION: u32 = 4;
|
||||
|
|
|
@ -49,12 +49,13 @@ pub struct Buffer {
|
|||
replica_id: ReplicaId,
|
||||
remote_id: u64,
|
||||
local_clock: clock::Local,
|
||||
lamport_clock: clock::Lamport,
|
||||
pub lamport_clock: clock::Lamport,
|
||||
subscriptions: Topic,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BufferSnapshot {
|
||||
replica_id: ReplicaId,
|
||||
visible_text: Rope,
|
||||
deleted_text: Rope,
|
||||
undo_map: UndoMap,
|
||||
|
@ -464,6 +465,7 @@ impl Buffer {
|
|||
|
||||
Buffer {
|
||||
snapshot: BufferSnapshot {
|
||||
replica_id,
|
||||
visible_text,
|
||||
deleted_text: Rope::new(),
|
||||
fragments,
|
||||
|
@ -495,14 +497,6 @@ impl Buffer {
|
|||
self.local_clock.replica_id
|
||||
}
|
||||
|
||||
pub fn lamport_timestamp(&self) -> clock::Lamport {
|
||||
self.lamport_clock
|
||||
}
|
||||
|
||||
pub fn observe_lamport_timestamp(&mut self, timestamp: clock::Lamport) {
|
||||
self.lamport_clock.observe(timestamp);
|
||||
}
|
||||
|
||||
pub fn remote_id(&self) -> u64 {
|
||||
self.remote_id
|
||||
}
|
||||
|
@ -1219,6 +1213,10 @@ impl BufferSnapshot {
|
|||
&self.visible_text
|
||||
}
|
||||
|
||||
pub fn replica_id(&self) -> ReplicaId {
|
||||
self.replica_id
|
||||
}
|
||||
|
||||
pub fn row_count(&self) -> u32 {
|
||||
self.max_point().row + 1
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
cd server
|
||||
cargo run --features seed-support --bin seed
|
||||
cargo run --package=zed-server --features seed-support --bin seed
|
||||
|
|
Loading…
Reference in a new issue