Introduce a ViewId message, identifying views across calls

This commit is contained in:
Max Brunsfeld 2022-12-14 14:40:07 -08:00
parent 43b7e16c89
commit 70efd2bebe
6 changed files with 134 additions and 38 deletions

View file

@ -84,7 +84,7 @@ use std::{
pub use sum_tree::Bias;
use theme::{DiagnosticStyle, Theme};
use util::{post_inc, ResultExt, TryFutureExt};
use workspace::{ItemNavHistory, Workspace, WorkspaceId};
use workspace::{ItemNavHistory, ViewId, Workspace, WorkspaceId};
use crate::git::diff_hunk_to_display;
@ -467,6 +467,7 @@ pub struct Editor {
keymap_context_layers: BTreeMap<TypeId, gpui::keymap::Context>,
input_enabled: bool,
leader_replica_id: Option<u16>,
remote_id: Option<ViewId>,
hover_state: HoverState,
link_go_to_definition_state: LinkGoToDefinitionState,
_subscriptions: Vec<Subscription>,
@ -1108,6 +1109,7 @@ impl Editor {
keymap_context_layers: Default::default(),
input_enabled: true,
leader_replica_id: None,
remote_id: None,
hover_state: Default::default(),
link_go_to_definition_state: Default::default(),
_subscriptions: vec![

View file

@ -3,6 +3,7 @@ use std::{cell::RefCell, rc::Rc, time::Instant};
use drag_and_drop::DragAndDrop;
use futures::StreamExt;
use indoc::indoc;
use rpc::PeerId;
use unindent::Unindent;
use super::*;
@ -24,7 +25,7 @@ use util::{
};
use workspace::{
item::{FollowableItem, ItemHandle},
NavigationEntry, Pane,
NavigationEntry, Pane, ViewId,
};
#[gpui::test]
@ -5123,7 +5124,16 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) {
let mut state_message = leader.update(cx, |leader, cx| leader.to_state_proto(cx));
let follower_1 = cx
.update(|cx| {
Editor::from_state_proto(pane.clone(), project.clone(), &mut state_message, cx)
Editor::from_state_proto(
pane.clone(),
project.clone(),
ViewId {
creator: PeerId(0),
id: 0,
},
&mut state_message,
cx,
)
})
.unwrap()
.await
@ -5209,7 +5219,16 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) {
let mut state_message = leader.update(cx, |leader, cx| leader.to_state_proto(cx));
let follower_2 = cx
.update(|cx| {
Editor::from_state_proto(pane.clone(), project.clone(), &mut state_message, cx)
Editor::from_state_proto(
pane.clone(),
project.clone(),
ViewId {
creator: PeerId(0),
id: 0,
},
&mut state_message,
cx,
)
})
.unwrap()
.await

View file

@ -28,24 +28,32 @@ use std::{
};
use text::Selection;
use util::{ResultExt, TryFutureExt};
use workspace::item::FollowableItemHandle;
use workspace::{
item::{FollowableItem, Item, ItemEvent, ItemHandle, ProjectItem},
searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle},
ItemId, ItemNavHistory, Pane, StatusItemView, ToolbarItemLocation, Workspace, WorkspaceId,
ItemId, ItemNavHistory, Pane, StatusItemView, ToolbarItemLocation, ViewId, Workspace,
WorkspaceId,
};
pub const MAX_TAB_TITLE_LEN: usize = 24;
impl FollowableItem for Editor {
fn remote_id(&self) -> Option<ViewId> {
self.remote_id
}
fn from_state_proto(
pane: ViewHandle<workspace::Pane>,
project: ModelHandle<Project>,
remote_id: ViewId,
state: &mut Option<proto::view::Variant>,
cx: &mut MutableAppContext,
) -> Option<Task<Result<ViewHandle<Self>>>> {
let Some(proto::view::Variant::Editor(_)) = state else { return None };
let Some(proto::view::Variant::Editor(state)) = state.take() else { unreachable!() };
let client = project.read(cx).client();
let replica_id = project.read(cx).replica_id();
let buffer_ids = state
.excerpts
@ -63,13 +71,13 @@ impl FollowableItem for Editor {
let mut buffers = futures::future::try_join_all(buffers).await?;
let editor = pane.read_with(&cx, |pane, cx| {
let mut editors = pane.items_of_type::<Self>();
if state.singleton && buffers.len() == 1 {
editors.find(|editor| {
editor.read(cx).buffer.read(cx).as_singleton().as_ref() == Some(&buffers[0])
})
} else {
None
}
editors.find(|editor| {
editor.remote_id(&client, cx) == Some(remote_id)
|| state.singleton
&& buffers.len() == 1
&& editor.read(cx).buffer.read(cx).as_singleton().as_ref()
== Some(&buffers[0])
})
});
let editor = editor.unwrap_or_else(|| {
@ -112,6 +120,7 @@ impl FollowableItem for Editor {
});
editor.update(&mut cx, |editor, cx| {
editor.remote_id = Some(remote_id);
let buffer = editor.buffer.read(cx).read(cx);
let selections = state
.selections