rpc.rs

   1// mod store;
   2
   3// use super::{
   4//     auth::process_auth_header,
   5//     db::{ChannelId, MessageId, UserId},
   6//     AppState,
   7// };
   8// use anyhow::anyhow;
   9// use async_std::{
  10//     sync::{RwLock, RwLockReadGuard, RwLockWriteGuard},
  11//     task,
  12// };
  13// use async_tungstenite::{tungstenite::protocol::Role, WebSocketStream};
  14// use collections::{HashMap, HashSet};
  15// use futures::{channel::mpsc, future::BoxFuture, FutureExt, SinkExt, StreamExt};
  16// use log::{as_debug, as_display};
  17// use rpc::{
  18//     proto::{self, AnyTypedEnvelope, EntityMessage, EnvelopedMessage, RequestMessage},
  19//     Connection, ConnectionId, Peer, TypedEnvelope,
  20// };
  21// use sha1::{Digest as _, Sha1};
  22// use std::{
  23//     any::TypeId,
  24//     future::Future,
  25//     marker::PhantomData,
  26//     ops::{Deref, DerefMut},
  27//     rc::Rc,
  28//     sync::Arc,
  29//     time::{Duration, Instant},
  30// };
  31// use store::{Store, Worktree};
  32// use time::OffsetDateTime;
  33// use util::ResultExt;
  34
  35// type MessageHandler = Box<
  36//     dyn Send
  37//         + Sync
  38//         + Fn(Arc<Server>, Box<dyn AnyTypedEnvelope>) -> BoxFuture<'static, tide::Result<()>>,
  39// >;
  40
  41// pub struct Server {
  42//     peer: Arc<Peer>,
  43//     store: RwLock<Store>,
  44//     app_state: Arc<AppState>,
  45//     handlers: HashMap<TypeId, MessageHandler>,
  46//     notifications: Option<mpsc::UnboundedSender<()>>,
  47// }
  48
  49// pub trait Executor: Send + Clone {
  50//     type Timer: Send + Future;
  51//     fn spawn_detached<F: 'static + Send + Future<Output = ()>>(&self, future: F);
  52//     fn timer(&self, duration: Duration) -> Self::Timer;
  53// }
  54
  55// #[derive(Clone)]
  56// pub struct RealExecutor;
  57
  58// const MESSAGE_COUNT_PER_PAGE: usize = 100;
  59// const MAX_MESSAGE_LEN: usize = 1024;
  60
  61// struct StoreReadGuard<'a> {
  62//     guard: RwLockReadGuard<'a, Store>,
  63//     _not_send: PhantomData<Rc<()>>,
  64// }
  65
  66// struct StoreWriteGuard<'a> {
  67//     guard: RwLockWriteGuard<'a, Store>,
  68//     _not_send: PhantomData<Rc<()>>,
  69// }
  70
  71// impl Server {
  72//     pub fn new(
  73//         app_state: Arc<AppState>,
  74//         peer: Arc<Peer>,
  75//         notifications: Option<mpsc::UnboundedSender<()>>,
  76//     ) -> Arc<Self> {
  77//         let mut server = Self {
  78//             peer,
  79//             app_state,
  80//             store: Default::default(),
  81//             handlers: Default::default(),
  82//             notifications,
  83//         };
  84
  85//         server
  86//             .add_request_handler(Server::ping)
  87//             .add_request_handler(Server::register_project)
  88//             .add_message_handler(Server::unregister_project)
  89//             .add_request_handler(Server::share_project)
  90//             .add_message_handler(Server::unshare_project)
  91//             .add_sync_request_handler(Server::join_project)
  92//             .add_message_handler(Server::leave_project)
  93//             .add_request_handler(Server::register_worktree)
  94//             .add_message_handler(Server::unregister_worktree)
  95//             .add_request_handler(Server::update_worktree)
  96//             .add_message_handler(Server::start_language_server)
  97//             .add_message_handler(Server::update_language_server)
  98//             .add_message_handler(Server::update_diagnostic_summary)
  99//             .add_request_handler(Server::forward_project_request::<proto::GetDefinition>)
 100//             .add_request_handler(Server::forward_project_request::<proto::GetReferences>)
 101//             .add_request_handler(Server::forward_project_request::<proto::SearchProject>)
 102//             .add_request_handler(Server::forward_project_request::<proto::GetDocumentHighlights>)
 103//             .add_request_handler(Server::forward_project_request::<proto::GetProjectSymbols>)
 104//             .add_request_handler(Server::forward_project_request::<proto::OpenBufferForSymbol>)
 105//             .add_request_handler(Server::forward_project_request::<proto::OpenBufferById>)
 106//             .add_request_handler(Server::forward_project_request::<proto::OpenBufferByPath>)
 107//             .add_request_handler(Server::forward_project_request::<proto::GetCompletions>)
 108//             .add_request_handler(
 109//                 Server::forward_project_request::<proto::ApplyCompletionAdditionalEdits>,
 110//             )
 111//             .add_request_handler(Server::forward_project_request::<proto::GetCodeActions>)
 112//             .add_request_handler(Server::forward_project_request::<proto::ApplyCodeAction>)
 113//             .add_request_handler(Server::forward_project_request::<proto::PrepareRename>)
 114//             .add_request_handler(Server::forward_project_request::<proto::PerformRename>)
 115//             .add_request_handler(Server::forward_project_request::<proto::ReloadBuffers>)
 116//             .add_request_handler(Server::forward_project_request::<proto::FormatBuffers>)
 117//             .add_request_handler(Server::update_buffer)
 118//             .add_message_handler(Server::update_buffer_file)
 119//             .add_message_handler(Server::buffer_reloaded)
 120//             .add_message_handler(Server::buffer_saved)
 121//             .add_request_handler(Server::save_buffer)
 122//             .add_request_handler(Server::get_channels)
 123//             .add_request_handler(Server::get_users)
 124//             .add_request_handler(Server::join_channel)
 125//             .add_message_handler(Server::leave_channel)
 126//             .add_request_handler(Server::send_channel_message)
 127//             .add_request_handler(Server::follow)
 128//             .add_message_handler(Server::unfollow)
 129//             .add_message_handler(Server::update_followers)
 130//             .add_request_handler(Server::get_channel_messages);
 131
 132//         Arc::new(server)
 133//     }
 134
 135//     fn add_message_handler<F, Fut, M>(&mut self, handler: F) -> &mut Self
 136//     where
 137//         F: 'static + Send + Sync + Fn(Arc<Self>, TypedEnvelope<M>) -> Fut,
 138//         Fut: 'static + Send + Future<Output = tide::Result<()>>,
 139//         M: EnvelopedMessage,
 140//     {
 141//         let prev_handler = self.handlers.insert(
 142//             TypeId::of::<M>(),
 143//             Box::new(move |server, envelope| {
 144//                 let envelope = envelope.into_any().downcast::<TypedEnvelope<M>>().unwrap();
 145//                 (handler)(server, *envelope).boxed()
 146//             }),
 147//         );
 148//         if prev_handler.is_some() {
 149//             panic!("registered a handler for the same message twice");
 150//         }
 151//         self
 152//     }
 153
 154//     fn add_request_handler<F, Fut, M>(&mut self, handler: F) -> &mut Self
 155//     where
 156//         F: 'static + Send + Sync + Fn(Arc<Self>, TypedEnvelope<M>) -> Fut,
 157//         Fut: 'static + Send + Future<Output = tide::Result<M::Response>>,
 158//         M: RequestMessage,
 159//     {
 160//         self.add_message_handler(move |server, envelope| {
 161//             let receipt = envelope.receipt();
 162//             let response = (handler)(server.clone(), envelope);
 163//             async move {
 164//                 match response.await {
 165//                     Ok(response) => {
 166//                         server.peer.respond(receipt, response)?;
 167//                         Ok(())
 168//                     }
 169//                     Err(error) => {
 170//                         server.peer.respond_with_error(
 171//                             receipt,
 172//                             proto::Error {
 173//                                 message: error.to_string(),
 174//                             },
 175//                         )?;
 176//                         Err(error)
 177//                     }
 178//                 }
 179//             }
 180//         })
 181//     }
 182
 183//     /// Handle a request while holding a lock to the store. This is useful when we're registering
 184//     /// a connection but we want to respond on the connection before anybody else can send on it.
 185//     fn add_sync_request_handler<F, M>(&mut self, handler: F) -> &mut Self
 186//     where
 187//         F: 'static
 188//             + Send
 189//             + Sync
 190//             + Fn(Arc<Self>, &mut Store, TypedEnvelope<M>) -> tide::Result<M::Response>,
 191//         M: RequestMessage,
 192//     {
 193//         let handler = Arc::new(handler);
 194//         self.add_message_handler(move |server, envelope| {
 195//             let receipt = envelope.receipt();
 196//             let handler = handler.clone();
 197//             async move {
 198//                 let mut store = server.store.write().await;
 199//                 let response = (handler)(server.clone(), &mut *store, envelope);
 200//                 match response {
 201//                     Ok(response) => {
 202//                         server.peer.respond(receipt, response)?;
 203//                         Ok(())
 204//                     }
 205//                     Err(error) => {
 206//                         server.peer.respond_with_error(
 207//                             receipt,
 208//                             proto::Error {
 209//                                 message: error.to_string(),
 210//                             },
 211//                         )?;
 212//                         Err(error)
 213//                     }
 214//                 }
 215//             }
 216//         })
 217//     }
 218
 219//     pub fn handle_connection<E: Executor>(
 220//         self: &Arc<Self>,
 221//         connection: Connection,
 222//         addr: String,
 223//         user_id: UserId,
 224//         mut send_connection_id: Option<mpsc::Sender<ConnectionId>>,
 225//         executor: E,
 226//     ) -> impl Future<Output = ()> {
 227//         let mut this = self.clone();
 228//         async move {
 229//             let (connection_id, handle_io, mut incoming_rx) = this
 230//                 .peer
 231//                 .add_connection(connection, {
 232//                     let executor = executor.clone();
 233//                     move |duration| {
 234//                         let timer = executor.timer(duration);
 235//                         async move {
 236//                             timer.await;
 237//                         }
 238//                     }
 239//                 })
 240//                 .await;
 241
 242//             if let Some(send_connection_id) = send_connection_id.as_mut() {
 243//                 let _ = send_connection_id.send(connection_id).await;
 244//             }
 245
 246//             {
 247//                 let mut state = this.state_mut().await;
 248//                 state.add_connection(connection_id, user_id);
 249//                 this.update_contacts_for_users(&*state, &[user_id]);
 250//             }
 251
 252//             let handle_io = handle_io.fuse();
 253//             futures::pin_mut!(handle_io);
 254//             loop {
 255//                 let next_message = incoming_rx.next().fuse();
 256//                 futures::pin_mut!(next_message);
 257//                 futures::select_biased! {
 258//                     result = handle_io => {
 259//                         if let Err(err) = result {
 260//                             log::error!("error handling rpc connection {:?} - {:?}", addr, err);
 261//                         }
 262//                         break;
 263//                     }
 264//                     message = next_message => {
 265//                         if let Some(message) = message {
 266//                             let start_time = Instant::now();
 267//                             let type_name = message.payload_type_name();
 268//                             log::info!(connection_id = connection_id.0, type_name = type_name; "rpc message received");
 269//                             if let Some(handler) = this.handlers.get(&message.payload_type_id()) {
 270//                                 let notifications = this.notifications.clone();
 271//                                 let is_background = message.is_background();
 272//                                 let handle_message = (handler)(this.clone(), message);
 273//                                 let handle_message = async move {
 274//                                     if let Err(err) = handle_message.await {
 275//                                         log::error!(connection_id = connection_id.0, type = type_name, error = as_display!(err); "rpc message error");
 276//                                     } else {
 277//                                         log::info!(connection_id = connection_id.0, type = type_name, duration = as_debug!(start_time.elapsed()); "rpc message handled");
 278//                                     }
 279//                                     if let Some(mut notifications) = notifications {
 280//                                         let _ = notifications.send(()).await;
 281//                                     }
 282//                                 };
 283//                                 if is_background {
 284//                                     executor.spawn_detached(handle_message);
 285//                                 } else {
 286//                                     handle_message.await;
 287//                                 }
 288//                             } else {
 289//                                 log::warn!("unhandled message: {}", type_name);
 290//                             }
 291//                         } else {
 292//                             log::info!(address = as_debug!(addr); "rpc connection closed");
 293//                             break;
 294//                         }
 295//                     }
 296//                 }
 297//             }
 298
 299//             if let Err(err) = this.sign_out(connection_id).await {
 300//                 log::error!("error signing out connection {:?} - {:?}", addr, err);
 301//             }
 302//         }
 303//     }
 304
 305//     async fn sign_out(self: &mut Arc<Self>, connection_id: ConnectionId) -> tide::Result<()> {
 306//         self.peer.disconnect(connection_id);
 307//         let mut state = self.state_mut().await;
 308//         let removed_connection = state.remove_connection(connection_id)?;
 309
 310//         for (project_id, project) in removed_connection.hosted_projects {
 311//             if let Some(share) = project.share {
 312//                 broadcast(
 313//                     connection_id,
 314//                     share.guests.keys().copied().collect(),
 315//                     |conn_id| {
 316//                         self.peer
 317//                             .send(conn_id, proto::UnshareProject { project_id })
 318//                     },
 319//                 );
 320//             }
 321//         }
 322
 323//         for (project_id, peer_ids) in removed_connection.guest_project_ids {
 324//             broadcast(connection_id, peer_ids, |conn_id| {
 325//                 self.peer.send(
 326//                     conn_id,
 327//                     proto::RemoveProjectCollaborator {
 328//                         project_id,
 329//                         peer_id: connection_id.0,
 330//                     },
 331//                 )
 332//             });
 333//         }
 334
 335//         self.update_contacts_for_users(&*state, removed_connection.contact_ids.iter());
 336//         Ok(())
 337//     }
 338
 339//     async fn ping(self: Arc<Server>, _: TypedEnvelope<proto::Ping>) -> tide::Result<proto::Ack> {
 340//         Ok(proto::Ack {})
 341//     }
 342
 343//     async fn register_project(
 344//         self: Arc<Server>,
 345//         request: TypedEnvelope<proto::RegisterProject>,
 346//     ) -> tide::Result<proto::RegisterProjectResponse> {
 347//         let project_id = {
 348//             let mut state = self.state_mut().await;
 349//             let user_id = state.user_id_for_connection(request.sender_id)?;
 350//             state.register_project(request.sender_id, user_id)
 351//         };
 352//         Ok(proto::RegisterProjectResponse { project_id })
 353//     }
 354
 355//     async fn unregister_project(
 356//         self: Arc<Server>,
 357//         request: TypedEnvelope<proto::UnregisterProject>,
 358//     ) -> tide::Result<()> {
 359//         let mut state = self.state_mut().await;
 360//         let project = state.unregister_project(request.payload.project_id, request.sender_id)?;
 361//         self.update_contacts_for_users(&*state, &project.authorized_user_ids());
 362//         Ok(())
 363//     }
 364
 365//     async fn share_project(
 366//         self: Arc<Server>,
 367//         request: TypedEnvelope<proto::ShareProject>,
 368//     ) -> tide::Result<proto::Ack> {
 369//         let mut state = self.state_mut().await;
 370//         let project = state.share_project(request.payload.project_id, request.sender_id)?;
 371//         self.update_contacts_for_users(&mut *state, &project.authorized_user_ids);
 372//         Ok(proto::Ack {})
 373//     }
 374
 375//     async fn unshare_project(
 376//         self: Arc<Server>,
 377//         request: TypedEnvelope<proto::UnshareProject>,
 378//     ) -> tide::Result<()> {
 379//         let project_id = request.payload.project_id;
 380//         let mut state = self.state_mut().await;
 381//         let project = state.unshare_project(project_id, request.sender_id)?;
 382//         broadcast(request.sender_id, project.connection_ids, |conn_id| {
 383//             self.peer
 384//                 .send(conn_id, proto::UnshareProject { project_id })
 385//         });
 386//         self.update_contacts_for_users(&mut *state, &project.authorized_user_ids);
 387//         Ok(())
 388//     }
 389
 390//     fn join_project(
 391//         self: Arc<Server>,
 392//         state: &mut Store,
 393//         request: TypedEnvelope<proto::JoinProject>,
 394//     ) -> tide::Result<proto::JoinProjectResponse> {
 395//         let project_id = request.payload.project_id;
 396
 397//         let user_id = state.user_id_for_connection(request.sender_id)?;
 398//         let (response, connection_ids, contact_user_ids) = state
 399//             .join_project(request.sender_id, user_id, project_id)
 400//             .and_then(|joined| {
 401//                 let share = joined.project.share()?;
 402//                 let peer_count = share.guests.len();
 403//                 let mut collaborators = Vec::with_capacity(peer_count);
 404//                 collaborators.push(proto::Collaborator {
 405//                     peer_id: joined.project.host_connection_id.0,
 406//                     replica_id: 0,
 407//                     user_id: joined.project.host_user_id.to_proto(),
 408//                 });
 409//                 let worktrees = share
 410//                     .worktrees
 411//                     .iter()
 412//                     .filter_map(|(id, shared_worktree)| {
 413//                         let worktree = joined.project.worktrees.get(&id)?;
 414//                         Some(proto::Worktree {
 415//                             id: *id,
 416//                             root_name: worktree.root_name.clone(),
 417//                             entries: shared_worktree.entries.values().cloned().collect(),
 418//                             diagnostic_summaries: shared_worktree
 419//                                 .diagnostic_summaries
 420//                                 .values()
 421//                                 .cloned()
 422//                                 .collect(),
 423//                             visible: worktree.visible,
 424//                         })
 425//                     })
 426//                     .collect();
 427//                 for (peer_conn_id, (peer_replica_id, peer_user_id)) in &share.guests {
 428//                     if *peer_conn_id != request.sender_id {
 429//                         collaborators.push(proto::Collaborator {
 430//                             peer_id: peer_conn_id.0,
 431//                             replica_id: *peer_replica_id as u32,
 432//                             user_id: peer_user_id.to_proto(),
 433//                         });
 434//                     }
 435//                 }
 436//                 let response = proto::JoinProjectResponse {
 437//                     worktrees,
 438//                     replica_id: joined.replica_id as u32,
 439//                     collaborators,
 440//                     language_servers: joined.project.language_servers.clone(),
 441//                 };
 442//                 let connection_ids = joined.project.connection_ids();
 443//                 let contact_user_ids = joined.project.authorized_user_ids();
 444//                 Ok((response, connection_ids, contact_user_ids))
 445//             })?;
 446
 447//         broadcast(request.sender_id, connection_ids, |conn_id| {
 448//             self.peer.send(
 449//                 conn_id,
 450//                 proto::AddProjectCollaborator {
 451//                     project_id,
 452//                     collaborator: Some(proto::Collaborator {
 453//                         peer_id: request.sender_id.0,
 454//                         replica_id: response.replica_id,
 455//                         user_id: user_id.to_proto(),
 456//                     }),
 457//                 },
 458//             )
 459//         });
 460//         self.update_contacts_for_users(state, &contact_user_ids);
 461//         Ok(response)
 462//     }
 463
 464//     async fn leave_project(
 465//         self: Arc<Server>,
 466//         request: TypedEnvelope<proto::LeaveProject>,
 467//     ) -> tide::Result<()> {
 468//         let sender_id = request.sender_id;
 469//         let project_id = request.payload.project_id;
 470//         let mut state = self.state_mut().await;
 471//         let worktree = state.leave_project(sender_id, project_id)?;
 472//         broadcast(sender_id, worktree.connection_ids, |conn_id| {
 473//             self.peer.send(
 474//                 conn_id,
 475//                 proto::RemoveProjectCollaborator {
 476//                     project_id,
 477//                     peer_id: sender_id.0,
 478//                 },
 479//             )
 480//         });
 481//         self.update_contacts_for_users(&*state, &worktree.authorized_user_ids);
 482//         Ok(())
 483//     }
 484
 485//     async fn register_worktree(
 486//         self: Arc<Server>,
 487//         request: TypedEnvelope<proto::RegisterWorktree>,
 488//     ) -> tide::Result<proto::Ack> {
 489//         let mut contact_user_ids = HashSet::default();
 490//         for github_login in &request.payload.authorized_logins {
 491//             let contact_user_id = self.app_state.db.create_user(github_login, false).await?;
 492//             contact_user_ids.insert(contact_user_id);
 493//         }
 494
 495//         let mut state = self.state_mut().await;
 496//         let host_user_id = state.user_id_for_connection(request.sender_id)?;
 497//         contact_user_ids.insert(host_user_id);
 498
 499//         let contact_user_ids = contact_user_ids.into_iter().collect::<Vec<_>>();
 500//         let guest_connection_ids = state
 501//             .read_project(request.payload.project_id, request.sender_id)?
 502//             .guest_connection_ids();
 503//         state.register_worktree(
 504//             request.payload.project_id,
 505//             request.payload.worktree_id,
 506//             request.sender_id,
 507//             Worktree {
 508//                 authorized_user_ids: contact_user_ids.clone(),
 509//                 root_name: request.payload.root_name.clone(),
 510//                 visible: request.payload.visible,
 511//             },
 512//         )?;
 513
 514//         broadcast(request.sender_id, guest_connection_ids, |connection_id| {
 515//             self.peer
 516//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 517//         });
 518//         self.update_contacts_for_users(&*state, &contact_user_ids);
 519//         Ok(proto::Ack {})
 520//     }
 521
 522//     async fn unregister_worktree(
 523//         self: Arc<Server>,
 524//         request: TypedEnvelope<proto::UnregisterWorktree>,
 525//     ) -> tide::Result<()> {
 526//         let project_id = request.payload.project_id;
 527//         let worktree_id = request.payload.worktree_id;
 528//         let mut state = self.state_mut().await;
 529//         let (worktree, guest_connection_ids) =
 530//             state.unregister_worktree(project_id, worktree_id, request.sender_id)?;
 531//         broadcast(request.sender_id, guest_connection_ids, |conn_id| {
 532//             self.peer.send(
 533//                 conn_id,
 534//                 proto::UnregisterWorktree {
 535//                     project_id,
 536//                     worktree_id,
 537//                 },
 538//             )
 539//         });
 540//         self.update_contacts_for_users(&*state, &worktree.authorized_user_ids);
 541//         Ok(())
 542//     }
 543
 544//     async fn update_worktree(
 545//         self: Arc<Server>,
 546//         request: TypedEnvelope<proto::UpdateWorktree>,
 547//     ) -> tide::Result<proto::Ack> {
 548//         let connection_ids = self.state_mut().await.update_worktree(
 549//             request.sender_id,
 550//             request.payload.project_id,
 551//             request.payload.worktree_id,
 552//             &request.payload.removed_entries,
 553//             &request.payload.updated_entries,
 554//         )?;
 555
 556//         broadcast(request.sender_id, connection_ids, |connection_id| {
 557//             self.peer
 558//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 559//         });
 560
 561//         Ok(proto::Ack {})
 562//     }
 563
 564//     async fn update_diagnostic_summary(
 565//         self: Arc<Server>,
 566//         request: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 567//     ) -> tide::Result<()> {
 568//         let summary = request
 569//             .payload
 570//             .summary
 571//             .clone()
 572//             .ok_or_else(|| anyhow!("invalid summary"))?;
 573//         let receiver_ids = self.state_mut().await.update_diagnostic_summary(
 574//             request.payload.project_id,
 575//             request.payload.worktree_id,
 576//             request.sender_id,
 577//             summary,
 578//         )?;
 579
 580//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 581//             self.peer
 582//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 583//         });
 584//         Ok(())
 585//     }
 586
 587//     async fn start_language_server(
 588//         self: Arc<Server>,
 589//         request: TypedEnvelope<proto::StartLanguageServer>,
 590//     ) -> tide::Result<()> {
 591//         let receiver_ids = self.state_mut().await.start_language_server(
 592//             request.payload.project_id,
 593//             request.sender_id,
 594//             request
 595//                 .payload
 596//                 .server
 597//                 .clone()
 598//                 .ok_or_else(|| anyhow!("invalid language server"))?,
 599//         )?;
 600//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 601//             self.peer
 602//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 603//         });
 604//         Ok(())
 605//     }
 606
 607//     async fn update_language_server(
 608//         self: Arc<Server>,
 609//         request: TypedEnvelope<proto::UpdateLanguageServer>,
 610//     ) -> tide::Result<()> {
 611//         let receiver_ids = self
 612//             .state()
 613//             .await
 614//             .project_connection_ids(request.payload.project_id, request.sender_id)?;
 615//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 616//             self.peer
 617//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 618//         });
 619//         Ok(())
 620//     }
 621
 622//     async fn forward_project_request<T>(
 623//         self: Arc<Server>,
 624//         request: TypedEnvelope<T>,
 625//     ) -> tide::Result<T::Response>
 626//     where
 627//         T: EntityMessage + RequestMessage,
 628//     {
 629//         let host_connection_id = self
 630//             .state()
 631//             .await
 632//             .read_project(request.payload.remote_entity_id(), request.sender_id)?
 633//             .host_connection_id;
 634//         Ok(self
 635//             .peer
 636//             .forward_request(request.sender_id, host_connection_id, request.payload)
 637//             .await?)
 638//     }
 639
 640//     async fn save_buffer(
 641//         self: Arc<Server>,
 642//         request: TypedEnvelope<proto::SaveBuffer>,
 643//     ) -> tide::Result<proto::BufferSaved> {
 644//         let host = self
 645//             .state()
 646//             .await
 647//             .read_project(request.payload.project_id, request.sender_id)?
 648//             .host_connection_id;
 649//         let response = self
 650//             .peer
 651//             .forward_request(request.sender_id, host, request.payload.clone())
 652//             .await?;
 653
 654//         let mut guests = self
 655//             .state()
 656//             .await
 657//             .read_project(request.payload.project_id, request.sender_id)?
 658//             .connection_ids();
 659//         guests.retain(|guest_connection_id| *guest_connection_id != request.sender_id);
 660//         broadcast(host, guests, |conn_id| {
 661//             self.peer.forward_send(host, conn_id, response.clone())
 662//         });
 663
 664//         Ok(response)
 665//     }
 666
 667//     async fn update_buffer(
 668//         self: Arc<Server>,
 669//         request: TypedEnvelope<proto::UpdateBuffer>,
 670//     ) -> tide::Result<proto::Ack> {
 671//         let receiver_ids = self
 672//             .state()
 673//             .await
 674//             .project_connection_ids(request.payload.project_id, request.sender_id)?;
 675//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 676//             self.peer
 677//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 678//         });
 679//         Ok(proto::Ack {})
 680//     }
 681
 682//     async fn update_buffer_file(
 683//         self: Arc<Server>,
 684//         request: TypedEnvelope<proto::UpdateBufferFile>,
 685//     ) -> tide::Result<()> {
 686//         let receiver_ids = self
 687//             .state()
 688//             .await
 689//             .project_connection_ids(request.payload.project_id, request.sender_id)?;
 690//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 691//             self.peer
 692//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 693//         });
 694//         Ok(())
 695//     }
 696
 697//     async fn buffer_reloaded(
 698//         self: Arc<Server>,
 699//         request: TypedEnvelope<proto::BufferReloaded>,
 700//     ) -> tide::Result<()> {
 701//         let receiver_ids = self
 702//             .state()
 703//             .await
 704//             .project_connection_ids(request.payload.project_id, request.sender_id)?;
 705//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 706//             self.peer
 707//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 708//         });
 709//         Ok(())
 710//     }
 711
 712//     async fn buffer_saved(
 713//         self: Arc<Server>,
 714//         request: TypedEnvelope<proto::BufferSaved>,
 715//     ) -> tide::Result<()> {
 716//         let receiver_ids = self
 717//             .state()
 718//             .await
 719//             .project_connection_ids(request.payload.project_id, request.sender_id)?;
 720//         broadcast(request.sender_id, receiver_ids, |connection_id| {
 721//             self.peer
 722//                 .forward_send(request.sender_id, connection_id, request.payload.clone())
 723//         });
 724//         Ok(())
 725//     }
 726
 727//     async fn follow(
 728//         self: Arc<Self>,
 729//         request: TypedEnvelope<proto::Follow>,
 730//     ) -> tide::Result<proto::FollowResponse> {
 731//         let leader_id = ConnectionId(request.payload.leader_id);
 732//         let follower_id = request.sender_id;
 733//         if !self
 734//             .state()
 735//             .await
 736//             .project_connection_ids(request.payload.project_id, follower_id)?
 737//             .contains(&leader_id)
 738//         {
 739//             Err(anyhow!("no such peer"))?;
 740//         }
 741//         let mut response = self
 742//             .peer
 743//             .forward_request(request.sender_id, leader_id, request.payload)
 744//             .await?;
 745//         response
 746//             .views
 747//             .retain(|view| view.leader_id != Some(follower_id.0));
 748//         Ok(response)
 749//     }
 750
 751//     async fn unfollow(
 752//         self: Arc<Self>,
 753//         request: TypedEnvelope<proto::Unfollow>,
 754//     ) -> tide::Result<()> {
 755//         let leader_id = ConnectionId(request.payload.leader_id);
 756//         if !self
 757//             .state()
 758//             .await
 759//             .project_connection_ids(request.payload.project_id, request.sender_id)?
 760//             .contains(&leader_id)
 761//         {
 762//             Err(anyhow!("no such peer"))?;
 763//         }
 764//         self.peer
 765//             .forward_send(request.sender_id, leader_id, request.payload)?;
 766//         Ok(())
 767//     }
 768
 769//     async fn update_followers(
 770//         self: Arc<Self>,
 771//         request: TypedEnvelope<proto::UpdateFollowers>,
 772//     ) -> tide::Result<()> {
 773//         let connection_ids = self
 774//             .state()
 775//             .await
 776//             .project_connection_ids(request.payload.project_id, request.sender_id)?;
 777//         let leader_id = request
 778//             .payload
 779//             .variant
 780//             .as_ref()
 781//             .and_then(|variant| match variant {
 782//                 proto::update_followers::Variant::CreateView(payload) => payload.leader_id,
 783//                 proto::update_followers::Variant::UpdateView(payload) => payload.leader_id,
 784//                 proto::update_followers::Variant::UpdateActiveView(payload) => payload.leader_id,
 785//             });
 786//         for follower_id in &request.payload.follower_ids {
 787//             let follower_id = ConnectionId(*follower_id);
 788//             if connection_ids.contains(&follower_id) && Some(follower_id.0) != leader_id {
 789//                 self.peer
 790//                     .forward_send(request.sender_id, follower_id, request.payload.clone())?;
 791//             }
 792//         }
 793//         Ok(())
 794//     }
 795
 796//     async fn get_channels(
 797//         self: Arc<Server>,
 798//         request: TypedEnvelope<proto::GetChannels>,
 799//     ) -> tide::Result<proto::GetChannelsResponse> {
 800//         let user_id = self
 801//             .state()
 802//             .await
 803//             .user_id_for_connection(request.sender_id)?;
 804//         let channels = self.app_state.db.get_accessible_channels(user_id).await?;
 805//         Ok(proto::GetChannelsResponse {
 806//             channels: channels
 807//                 .into_iter()
 808//                 .map(|chan| proto::Channel {
 809//                     id: chan.id.to_proto(),
 810//                     name: chan.name,
 811//                 })
 812//                 .collect(),
 813//         })
 814//     }
 815
 816//     async fn get_users(
 817//         self: Arc<Server>,
 818//         request: TypedEnvelope<proto::GetUsers>,
 819//     ) -> tide::Result<proto::GetUsersResponse> {
 820//         let user_ids = request
 821//             .payload
 822//             .user_ids
 823//             .into_iter()
 824//             .map(UserId::from_proto)
 825//             .collect();
 826//         let users = self
 827//             .app_state
 828//             .db
 829//             .get_users_by_ids(user_ids)
 830//             .await?
 831//             .into_iter()
 832//             .map(|user| proto::User {
 833//                 id: user.id.to_proto(),
 834//                 avatar_url: format!("https://github.com/{}.png?size=128", user.github_login),
 835//                 github_login: user.github_login,
 836//             })
 837//             .collect();
 838//         Ok(proto::GetUsersResponse { users })
 839//     }
 840
 841//     fn update_contacts_for_users<'a>(
 842//         self: &Arc<Self>,
 843//         state: &Store,
 844//         user_ids: impl IntoIterator<Item = &'a UserId>,
 845//     ) {
 846//         for user_id in user_ids {
 847//             let contacts = state.contacts_for_user(*user_id);
 848//             for connection_id in state.connection_ids_for_user(*user_id) {
 849//                 self.peer
 850//                     .send(
 851//                         connection_id,
 852//                         proto::UpdateContacts {
 853//                             contacts: contacts.clone(),
 854//                         },
 855//                     )
 856//                     .log_err();
 857//             }
 858//         }
 859//     }
 860
 861//     async fn join_channel(
 862//         self: Arc<Self>,
 863//         request: TypedEnvelope<proto::JoinChannel>,
 864//     ) -> tide::Result<proto::JoinChannelResponse> {
 865//         let user_id = self
 866//             .state()
 867//             .await
 868//             .user_id_for_connection(request.sender_id)?;
 869//         let channel_id = ChannelId::from_proto(request.payload.channel_id);
 870//         if !self
 871//             .app_state
 872//             .db
 873//             .can_user_access_channel(user_id, channel_id)
 874//             .await?
 875//         {
 876//             Err(anyhow!("access denied"))?;
 877//         }
 878
 879//         self.state_mut()
 880//             .await
 881//             .join_channel(request.sender_id, channel_id);
 882//         let messages = self
 883//             .app_state
 884//             .db
 885//             .get_channel_messages(channel_id, MESSAGE_COUNT_PER_PAGE, None)
 886//             .await?
 887//             .into_iter()
 888//             .map(|msg| proto::ChannelMessage {
 889//                 id: msg.id.to_proto(),
 890//                 body: msg.body,
 891//                 timestamp: msg.sent_at.unix_timestamp() as u64,
 892//                 sender_id: msg.sender_id.to_proto(),
 893//                 nonce: Some(msg.nonce.as_u128().into()),
 894//             })
 895//             .collect::<Vec<_>>();
 896//         Ok(proto::JoinChannelResponse {
 897//             done: messages.len() < MESSAGE_COUNT_PER_PAGE,
 898//             messages,
 899//         })
 900//     }
 901
 902//     async fn leave_channel(
 903//         self: Arc<Self>,
 904//         request: TypedEnvelope<proto::LeaveChannel>,
 905//     ) -> tide::Result<()> {
 906//         let user_id = self
 907//             .state()
 908//             .await
 909//             .user_id_for_connection(request.sender_id)?;
 910//         let channel_id = ChannelId::from_proto(request.payload.channel_id);
 911//         if !self
 912//             .app_state
 913//             .db
 914//             .can_user_access_channel(user_id, channel_id)
 915//             .await?
 916//         {
 917//             Err(anyhow!("access denied"))?;
 918//         }
 919
 920//         self.state_mut()
 921//             .await
 922//             .leave_channel(request.sender_id, channel_id);
 923
 924//         Ok(())
 925//     }
 926
 927//     async fn send_channel_message(
 928//         self: Arc<Self>,
 929//         request: TypedEnvelope<proto::SendChannelMessage>,
 930//     ) -> tide::Result<proto::SendChannelMessageResponse> {
 931//         let channel_id = ChannelId::from_proto(request.payload.channel_id);
 932//         let user_id;
 933//         let connection_ids;
 934//         {
 935//             let state = self.state().await;
 936//             user_id = state.user_id_for_connection(request.sender_id)?;
 937//             connection_ids = state.channel_connection_ids(channel_id)?;
 938//         }
 939
 940//         // Validate the message body.
 941//         let body = request.payload.body.trim().to_string();
 942//         if body.len() > MAX_MESSAGE_LEN {
 943//             return Err(anyhow!("message is too long"))?;
 944//         }
 945//         if body.is_empty() {
 946//             return Err(anyhow!("message can't be blank"))?;
 947//         }
 948
 949//         let timestamp = OffsetDateTime::now_utc();
 950//         let nonce = request
 951//             .payload
 952//             .nonce
 953//             .ok_or_else(|| anyhow!("nonce can't be blank"))?;
 954
 955//         let message_id = self
 956//             .app_state
 957//             .db
 958//             .create_channel_message(channel_id, user_id, &body, timestamp, nonce.clone().into())
 959//             .await?
 960//             .to_proto();
 961//         let message = proto::ChannelMessage {
 962//             sender_id: user_id.to_proto(),
 963//             id: message_id,
 964//             body,
 965//             timestamp: timestamp.unix_timestamp() as u64,
 966//             nonce: Some(nonce),
 967//         };
 968//         broadcast(request.sender_id, connection_ids, |conn_id| {
 969//             self.peer.send(
 970//                 conn_id,
 971//                 proto::ChannelMessageSent {
 972//                     channel_id: channel_id.to_proto(),
 973//                     message: Some(message.clone()),
 974//                 },
 975//             )
 976//         });
 977//         Ok(proto::SendChannelMessageResponse {
 978//             message: Some(message),
 979//         })
 980//     }
 981
 982//     async fn get_channel_messages(
 983//         self: Arc<Self>,
 984//         request: TypedEnvelope<proto::GetChannelMessages>,
 985//     ) -> tide::Result<proto::GetChannelMessagesResponse> {
 986//         let user_id = self
 987//             .state()
 988//             .await
 989//             .user_id_for_connection(request.sender_id)?;
 990//         let channel_id = ChannelId::from_proto(request.payload.channel_id);
 991//         if !self
 992//             .app_state
 993//             .db
 994//             .can_user_access_channel(user_id, channel_id)
 995//             .await?
 996//         {
 997//             Err(anyhow!("access denied"))?;
 998//         }
 999
1000//         let messages = self
1001//             .app_state
1002//             .db
1003//             .get_channel_messages(
1004//                 channel_id,
1005//                 MESSAGE_COUNT_PER_PAGE,
1006//                 Some(MessageId::from_proto(request.payload.before_message_id)),
1007//             )
1008//             .await?
1009//             .into_iter()
1010//             .map(|msg| proto::ChannelMessage {
1011//                 id: msg.id.to_proto(),
1012//                 body: msg.body,
1013//                 timestamp: msg.sent_at.unix_timestamp() as u64,
1014//                 sender_id: msg.sender_id.to_proto(),
1015//                 nonce: Some(msg.nonce.as_u128().into()),
1016//             })
1017//             .collect::<Vec<_>>();
1018
1019//         Ok(proto::GetChannelMessagesResponse {
1020//             done: messages.len() < MESSAGE_COUNT_PER_PAGE,
1021//             messages,
1022//         })
1023//     }
1024
1025//     async fn state<'a>(self: &'a Arc<Self>) -> StoreReadGuard<'a> {
1026//         #[cfg(test)]
1027//         async_std::task::yield_now().await;
1028//         let guard = self.store.read().await;
1029//         #[cfg(test)]
1030//         async_std::task::yield_now().await;
1031//         StoreReadGuard {
1032//             guard,
1033//             _not_send: PhantomData,
1034//         }
1035//     }
1036
1037//     async fn state_mut<'a>(self: &'a Arc<Self>) -> StoreWriteGuard<'a> {
1038//         #[cfg(test)]
1039//         async_std::task::yield_now().await;
1040//         let guard = self.store.write().await;
1041//         #[cfg(test)]
1042//         async_std::task::yield_now().await;
1043//         StoreWriteGuard {
1044//             guard,
1045//             _not_send: PhantomData,
1046//         }
1047//     }
1048// }
1049
1050// impl<'a> Deref for StoreReadGuard<'a> {
1051//     type Target = Store;
1052
1053//     fn deref(&self) -> &Self::Target {
1054//         &*self.guard
1055//     }
1056// }
1057
1058// impl<'a> Deref for StoreWriteGuard<'a> {
1059//     type Target = Store;
1060
1061//     fn deref(&self) -> &Self::Target {
1062//         &*self.guard
1063//     }
1064// }
1065
1066// impl<'a> DerefMut for StoreWriteGuard<'a> {
1067//     fn deref_mut(&mut self) -> &mut Self::Target {
1068//         &mut *self.guard
1069//     }
1070// }
1071
1072// impl<'a> Drop for StoreWriteGuard<'a> {
1073//     fn drop(&mut self) {
1074//         #[cfg(test)]
1075//         self.check_invariants();
1076//     }
1077// }
1078
1079// impl Executor for RealExecutor {
1080//     type Timer = Timer;
1081
1082//     fn spawn_detached<F: 'static + Send + Future<Output = ()>>(&self, future: F) {
1083//         task::spawn(future);
1084//     }
1085
1086//     fn timer(&self, duration: Duration) -> Self::Timer {
1087//         Timer::after(duration)
1088//     }
1089// }
1090
1091// fn broadcast<F>(sender_id: ConnectionId, receiver_ids: Vec<ConnectionId>, mut f: F)
1092// where
1093//     F: FnMut(ConnectionId) -> anyhow::Result<()>,
1094// {
1095//     for receiver_id in receiver_ids {
1096//         if receiver_id != sender_id {
1097//             f(receiver_id).log_err();
1098//         }
1099//     }
1100// }
1101
1102// pub fn add_routes(app: &mut tide::Server<Arc<AppState>>, rpc: &Arc<Peer>) {
1103//     let server = Server::new(app.state().clone(), rpc.clone(), None);
1104//     app.at("/rpc").get(move |request: Request<Arc<AppState>>| {
1105//         let server = server.clone();
1106//         async move {
1107//             const WEBSOCKET_GUID: &str = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
1108
1109//             let connection_upgrade = header_contains_ignore_case(&request, CONNECTION, "upgrade");
1110//             let upgrade_to_websocket = header_contains_ignore_case(&request, UPGRADE, "websocket");
1111//             let upgrade_requested = connection_upgrade && upgrade_to_websocket;
1112//             let client_protocol_version: Option<u32> = request
1113//                 .header("X-Zed-Protocol-Version")
1114//                 .and_then(|v| v.as_str().parse().ok());
1115
1116//             if !upgrade_requested || client_protocol_version != Some(rpc::PROTOCOL_VERSION) {
1117//                 return Ok(Response::new(StatusCode::UpgradeRequired));
1118//             }
1119
1120//             let header = match request.header("Sec-Websocket-Key") {
1121//                 Some(h) => h.as_str(),
1122//                 None => return Err(anyhow!("expected sec-websocket-key"))?,
1123//             };
1124
1125//             let user_id = process_auth_header(&request).await?;
1126
1127//             let mut response = Response::new(StatusCode::SwitchingProtocols);
1128//             response.insert_header(UPGRADE, "websocket");
1129//             response.insert_header(CONNECTION, "Upgrade");
1130//             let hash = Sha1::new().chain(header).chain(WEBSOCKET_GUID).finalize();
1131//             response.insert_header("Sec-Websocket-Accept", base64::encode(&hash[..]));
1132//             response.insert_header("Sec-Websocket-Version", "13");
1133
1134//             let http_res: &mut tide::http::Response = response.as_mut();
1135//             let upgrade_receiver = http_res.recv_upgrade().await;
1136//             let addr = request.remote().unwrap_or("unknown").to_string();
1137//             task::spawn(async move {
1138//                 if let Some(stream) = upgrade_receiver.await {
1139//                     server
1140//                         .handle_connection(
1141//                             Connection::new(
1142//                                 WebSocketStream::from_raw_socket(stream, Role::Server, None).await,
1143//                             ),
1144//                             addr,
1145//                             user_id,
1146//                             None,
1147//                             RealExecutor,
1148//                         )
1149//                         .await;
1150//                 }
1151//             });
1152
1153//             Ok(response)
1154//         }
1155//     });
1156// }
1157
1158// fn header_contains_ignore_case<T>(
1159//     request: &tide::Request<T>,
1160//     header_name: HeaderName,
1161//     value: &str,
1162// ) -> bool {
1163//     request
1164//         .header(header_name)
1165//         .map(|h| {
1166//             h.as_str()
1167//                 .split(',')
1168//                 .any(|s| s.trim().eq_ignore_ascii_case(value.trim()))
1169//         })
1170//         .unwrap_or(false)
1171// }
1172
1173// #[cfg(test)]
1174// mod tests {
1175//     use super::*;
1176//     use crate::{
1177//         db::{tests::TestDb, UserId},
1178//         AppState, Config,
1179//     };
1180//     use ::rpc::Peer;
1181//     use client::{
1182//         self, test::FakeHttpClient, Channel, ChannelDetails, ChannelList, Client, Credentials,
1183//         EstablishConnectionError, UserStore, RECEIVE_TIMEOUT,
1184//     };
1185//     use collections::BTreeMap;
1186//     use editor::{
1187//         self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Input, Redo, Rename,
1188//         ToOffset, ToggleCodeActions, Undo,
1189//     };
1190//     use gpui::{
1191//         executor::{self, Deterministic},
1192//         geometry::vector::vec2f,
1193//         ModelHandle, TestAppContext, ViewHandle,
1194//     };
1195//     use language::{
1196//         range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
1197//         LanguageConfig, LanguageRegistry, OffsetRangeExt, Point, Rope,
1198//     };
1199//     use lsp::{self, FakeLanguageServer};
1200//     use parking_lot::Mutex;
1201//     use project::{
1202//         fs::{FakeFs, Fs as _},
1203//         search::SearchQuery,
1204//         worktree::WorktreeHandle,
1205//         DiagnosticSummary, Project, ProjectPath, WorktreeId,
1206//     };
1207//     use rand::prelude::*;
1208//     use rpc::PeerId;
1209//     use serde_json::json;
1210//     use settings::Settings;
1211//     use sqlx::types::time::OffsetDateTime;
1212//     use std::{
1213//         env,
1214//         ops::Deref,
1215//         path::{Path, PathBuf},
1216//         rc::Rc,
1217//         sync::{
1218//             atomic::{AtomicBool, Ordering::SeqCst},
1219//             Arc,
1220//         },
1221//         time::Duration,
1222//     };
1223//     use theme::ThemeRegistry;
1224//     use workspace::{Item, SplitDirection, ToggleFollow, Workspace, WorkspaceParams};
1225
1226//     #[cfg(test)]
1227//     #[ctor::ctor]
1228//     fn init_logger() {
1229//         if std::env::var("RUST_LOG").is_ok() {
1230//             env_logger::init();
1231//         }
1232//     }
1233
1234//     #[gpui::test(iterations = 10)]
1235//     async fn test_share_project(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
1236//         let (window_b, _) = cx_b.add_window(|_| EmptyView);
1237//         let lang_registry = Arc::new(LanguageRegistry::test());
1238//         let fs = FakeFs::new(cx_a.background());
1239//         cx_a.foreground().forbid_parking();
1240
1241//         // Connect to a server as 2 clients.
1242//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1243//         let client_a = server.create_client(cx_a, "user_a").await;
1244//         let client_b = server.create_client(cx_b, "user_b").await;
1245
1246//         // Share a project as client A
1247//         fs.insert_tree(
1248//             "/a",
1249//             json!({
1250//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
1251//                 "a.txt": "a-contents",
1252//                 "b.txt": "b-contents",
1253//             }),
1254//         )
1255//         .await;
1256//         let project_a = cx_a.update(|cx| {
1257//             Project::local(
1258//                 client_a.clone(),
1259//                 client_a.user_store.clone(),
1260//                 lang_registry.clone(),
1261//                 fs.clone(),
1262//                 cx,
1263//             )
1264//         });
1265//         let (worktree_a, _) = project_a
1266//             .update(cx_a, |p, cx| {
1267//                 p.find_or_create_local_worktree("/a", true, cx)
1268//             })
1269//             .await
1270//             .unwrap();
1271//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1272//         worktree_a
1273//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1274//             .await;
1275//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1276//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1277
1278//         // Join that project as client B
1279//         let project_b = Project::remote(
1280//             project_id,
1281//             client_b.clone(),
1282//             client_b.user_store.clone(),
1283//             lang_registry.clone(),
1284//             fs.clone(),
1285//             &mut cx_b.to_async(),
1286//         )
1287//         .await
1288//         .unwrap();
1289
1290//         let replica_id_b = project_b.read_with(cx_b, |project, _| {
1291//             assert_eq!(
1292//                 project
1293//                     .collaborators()
1294//                     .get(&client_a.peer_id)
1295//                     .unwrap()
1296//                     .user
1297//                     .github_login,
1298//                 "user_a"
1299//             );
1300//             project.replica_id()
1301//         });
1302//         project_a
1303//             .condition(&cx_a, |tree, _| {
1304//                 tree.collaborators()
1305//                     .get(&client_b.peer_id)
1306//                     .map_or(false, |collaborator| {
1307//                         collaborator.replica_id == replica_id_b
1308//                             && collaborator.user.github_login == "user_b"
1309//                     })
1310//             })
1311//             .await;
1312
1313//         // Open the same file as client B and client A.
1314//         let buffer_b = project_b
1315//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "b.txt"), cx))
1316//             .await
1317//             .unwrap();
1318//         buffer_b.read_with(cx_b, |buf, _| assert_eq!(buf.text(), "b-contents"));
1319//         project_a.read_with(cx_a, |project, cx| {
1320//             assert!(project.has_open_buffer((worktree_id, "b.txt"), cx))
1321//         });
1322//         let buffer_a = project_a
1323//             .update(cx_a, |p, cx| p.open_buffer((worktree_id, "b.txt"), cx))
1324//             .await
1325//             .unwrap();
1326
1327//         let editor_b = cx_b.add_view(window_b, |cx| Editor::for_buffer(buffer_b, None, cx));
1328
1329//         // TODO
1330//         // // Create a selection set as client B and see that selection set as client A.
1331//         // buffer_a
1332//         //     .condition(&cx_a, |buffer, _| buffer.selection_sets().count() == 1)
1333//         //     .await;
1334
1335//         // Edit the buffer as client B and see that edit as client A.
1336//         editor_b.update(cx_b, |editor, cx| {
1337//             editor.handle_input(&Input("ok, ".into()), cx)
1338//         });
1339//         buffer_a
1340//             .condition(&cx_a, |buffer, _| buffer.text() == "ok, b-contents")
1341//             .await;
1342
1343//         // TODO
1344//         // // Remove the selection set as client B, see those selections disappear as client A.
1345//         cx_b.update(move |_| drop(editor_b));
1346//         // buffer_a
1347//         //     .condition(&cx_a, |buffer, _| buffer.selection_sets().count() == 0)
1348//         //     .await;
1349
1350//         // Dropping the client B's project removes client B from client A's collaborators.
1351//         cx_b.update(move |_| drop(project_b));
1352//         project_a
1353//             .condition(&cx_a, |project, _| project.collaborators().is_empty())
1354//             .await;
1355//     }
1356
1357//     #[gpui::test(iterations = 10)]
1358//     async fn test_unshare_project(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
1359//         let lang_registry = Arc::new(LanguageRegistry::test());
1360//         let fs = FakeFs::new(cx_a.background());
1361//         cx_a.foreground().forbid_parking();
1362
1363//         // Connect to a server as 2 clients.
1364//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1365//         let client_a = server.create_client(cx_a, "user_a").await;
1366//         let client_b = server.create_client(cx_b, "user_b").await;
1367
1368//         // Share a project as client A
1369//         fs.insert_tree(
1370//             "/a",
1371//             json!({
1372//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
1373//                 "a.txt": "a-contents",
1374//                 "b.txt": "b-contents",
1375//             }),
1376//         )
1377//         .await;
1378//         let project_a = cx_a.update(|cx| {
1379//             Project::local(
1380//                 client_a.clone(),
1381//                 client_a.user_store.clone(),
1382//                 lang_registry.clone(),
1383//                 fs.clone(),
1384//                 cx,
1385//             )
1386//         });
1387//         let (worktree_a, _) = project_a
1388//             .update(cx_a, |p, cx| {
1389//                 p.find_or_create_local_worktree("/a", true, cx)
1390//             })
1391//             .await
1392//             .unwrap();
1393//         worktree_a
1394//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1395//             .await;
1396//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1397//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1398//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1399//         assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
1400
1401//         // Join that project as client B
1402//         let project_b = Project::remote(
1403//             project_id,
1404//             client_b.clone(),
1405//             client_b.user_store.clone(),
1406//             lang_registry.clone(),
1407//             fs.clone(),
1408//             &mut cx_b.to_async(),
1409//         )
1410//         .await
1411//         .unwrap();
1412//         project_b
1413//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1414//             .await
1415//             .unwrap();
1416
1417//         // Unshare the project as client A
1418//         project_a.update(cx_a, |project, cx| project.unshare(cx));
1419//         project_b
1420//             .condition(cx_b, |project, _| project.is_read_only())
1421//             .await;
1422//         assert!(worktree_a.read_with(cx_a, |tree, _| !tree.as_local().unwrap().is_shared()));
1423//         cx_b.update(|_| {
1424//             drop(project_b);
1425//         });
1426
1427//         // Share the project again and ensure guests can still join.
1428//         project_a
1429//             .update(cx_a, |project, cx| project.share(cx))
1430//             .await
1431//             .unwrap();
1432//         assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
1433
1434//         let project_b2 = Project::remote(
1435//             project_id,
1436//             client_b.clone(),
1437//             client_b.user_store.clone(),
1438//             lang_registry.clone(),
1439//             fs.clone(),
1440//             &mut cx_b.to_async(),
1441//         )
1442//         .await
1443//         .unwrap();
1444//         project_b2
1445//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1446//             .await
1447//             .unwrap();
1448//     }
1449
1450//     #[gpui::test(iterations = 10)]
1451//     async fn test_host_disconnect(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
1452//         let lang_registry = Arc::new(LanguageRegistry::test());
1453//         let fs = FakeFs::new(cx_a.background());
1454//         cx_a.foreground().forbid_parking();
1455
1456//         // Connect to a server as 2 clients.
1457//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1458//         let client_a = server.create_client(cx_a, "user_a").await;
1459//         let client_b = server.create_client(cx_b, "user_b").await;
1460
1461//         // Share a project as client A
1462//         fs.insert_tree(
1463//             "/a",
1464//             json!({
1465//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
1466//                 "a.txt": "a-contents",
1467//                 "b.txt": "b-contents",
1468//             }),
1469//         )
1470//         .await;
1471//         let project_a = cx_a.update(|cx| {
1472//             Project::local(
1473//                 client_a.clone(),
1474//                 client_a.user_store.clone(),
1475//                 lang_registry.clone(),
1476//                 fs.clone(),
1477//                 cx,
1478//             )
1479//         });
1480//         let (worktree_a, _) = project_a
1481//             .update(cx_a, |p, cx| {
1482//                 p.find_or_create_local_worktree("/a", true, cx)
1483//             })
1484//             .await
1485//             .unwrap();
1486//         worktree_a
1487//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1488//             .await;
1489//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1490//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1491//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1492//         assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
1493
1494//         // Join that project as client B
1495//         let project_b = Project::remote(
1496//             project_id,
1497//             client_b.clone(),
1498//             client_b.user_store.clone(),
1499//             lang_registry.clone(),
1500//             fs.clone(),
1501//             &mut cx_b.to_async(),
1502//         )
1503//         .await
1504//         .unwrap();
1505//         project_b
1506//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1507//             .await
1508//             .unwrap();
1509
1510//         // Drop client A's connection. Collaborators should disappear and the project should not be shown as shared.
1511//         server.disconnect_client(client_a.current_user_id(cx_a));
1512//         cx_a.foreground().advance_clock(rpc::RECEIVE_TIMEOUT);
1513//         project_a
1514//             .condition(cx_a, |project, _| project.collaborators().is_empty())
1515//             .await;
1516//         project_a.read_with(cx_a, |project, _| assert!(!project.is_shared()));
1517//         project_b
1518//             .condition(cx_b, |project, _| project.is_read_only())
1519//             .await;
1520//         assert!(worktree_a.read_with(cx_a, |tree, _| !tree.as_local().unwrap().is_shared()));
1521//         cx_b.update(|_| {
1522//             drop(project_b);
1523//         });
1524
1525//         // Await reconnection
1526//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1527
1528//         // Share the project again and ensure guests can still join.
1529//         project_a
1530//             .update(cx_a, |project, cx| project.share(cx))
1531//             .await
1532//             .unwrap();
1533//         assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
1534
1535//         let project_b2 = Project::remote(
1536//             project_id,
1537//             client_b.clone(),
1538//             client_b.user_store.clone(),
1539//             lang_registry.clone(),
1540//             fs.clone(),
1541//             &mut cx_b.to_async(),
1542//         )
1543//         .await
1544//         .unwrap();
1545//         project_b2
1546//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1547//             .await
1548//             .unwrap();
1549//     }
1550
1551//     #[gpui::test(iterations = 10)]
1552//     async fn test_propagate_saves_and_fs_changes(
1553//         cx_a: &mut TestAppContext,
1554//         cx_b: &mut TestAppContext,
1555//         cx_c: &mut TestAppContext,
1556//     ) {
1557//         let lang_registry = Arc::new(LanguageRegistry::test());
1558//         let fs = FakeFs::new(cx_a.background());
1559//         cx_a.foreground().forbid_parking();
1560
1561//         // Connect to a server as 3 clients.
1562//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1563//         let client_a = server.create_client(cx_a, "user_a").await;
1564//         let client_b = server.create_client(cx_b, "user_b").await;
1565//         let client_c = server.create_client(cx_c, "user_c").await;
1566
1567//         // Share a worktree as client A.
1568//         fs.insert_tree(
1569//             "/a",
1570//             json!({
1571//                 ".zed.toml": r#"collaborators = ["user_b", "user_c"]"#,
1572//                 "file1": "",
1573//                 "file2": ""
1574//             }),
1575//         )
1576//         .await;
1577//         let project_a = cx_a.update(|cx| {
1578//             Project::local(
1579//                 client_a.clone(),
1580//                 client_a.user_store.clone(),
1581//                 lang_registry.clone(),
1582//                 fs.clone(),
1583//                 cx,
1584//             )
1585//         });
1586//         let (worktree_a, _) = project_a
1587//             .update(cx_a, |p, cx| {
1588//                 p.find_or_create_local_worktree("/a", true, cx)
1589//             })
1590//             .await
1591//             .unwrap();
1592//         worktree_a
1593//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1594//             .await;
1595//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1596//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1597//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1598
1599//         // Join that worktree as clients B and C.
1600//         let project_b = Project::remote(
1601//             project_id,
1602//             client_b.clone(),
1603//             client_b.user_store.clone(),
1604//             lang_registry.clone(),
1605//             fs.clone(),
1606//             &mut cx_b.to_async(),
1607//         )
1608//         .await
1609//         .unwrap();
1610//         let project_c = Project::remote(
1611//             project_id,
1612//             client_c.clone(),
1613//             client_c.user_store.clone(),
1614//             lang_registry.clone(),
1615//             fs.clone(),
1616//             &mut cx_c.to_async(),
1617//         )
1618//         .await
1619//         .unwrap();
1620//         let worktree_b = project_b.read_with(cx_b, |p, cx| p.worktrees(cx).next().unwrap());
1621//         let worktree_c = project_c.read_with(cx_c, |p, cx| p.worktrees(cx).next().unwrap());
1622
1623//         // Open and edit a buffer as both guests B and C.
1624//         let buffer_b = project_b
1625//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "file1"), cx))
1626//             .await
1627//             .unwrap();
1628//         let buffer_c = project_c
1629//             .update(cx_c, |p, cx| p.open_buffer((worktree_id, "file1"), cx))
1630//             .await
1631//             .unwrap();
1632//         buffer_b.update(cx_b, |buf, cx| buf.edit([0..0], "i-am-b, ", cx));
1633//         buffer_c.update(cx_c, |buf, cx| buf.edit([0..0], "i-am-c, ", cx));
1634
1635//         // Open and edit that buffer as the host.
1636//         let buffer_a = project_a
1637//             .update(cx_a, |p, cx| p.open_buffer((worktree_id, "file1"), cx))
1638//             .await
1639//             .unwrap();
1640
1641//         buffer_a
1642//             .condition(cx_a, |buf, _| buf.text() == "i-am-c, i-am-b, ")
1643//             .await;
1644//         buffer_a.update(cx_a, |buf, cx| {
1645//             buf.edit([buf.len()..buf.len()], "i-am-a", cx)
1646//         });
1647
1648//         // Wait for edits to propagate
1649//         buffer_a
1650//             .condition(cx_a, |buf, _| buf.text() == "i-am-c, i-am-b, i-am-a")
1651//             .await;
1652//         buffer_b
1653//             .condition(cx_b, |buf, _| buf.text() == "i-am-c, i-am-b, i-am-a")
1654//             .await;
1655//         buffer_c
1656//             .condition(cx_c, |buf, _| buf.text() == "i-am-c, i-am-b, i-am-a")
1657//             .await;
1658
1659//         // Edit the buffer as the host and concurrently save as guest B.
1660//         let save_b = buffer_b.update(cx_b, |buf, cx| buf.save(cx));
1661//         buffer_a.update(cx_a, |buf, cx| buf.edit([0..0], "hi-a, ", cx));
1662//         save_b.await.unwrap();
1663//         assert_eq!(
1664//             fs.load("/a/file1".as_ref()).await.unwrap(),
1665//             "hi-a, i-am-c, i-am-b, i-am-a"
1666//         );
1667//         buffer_a.read_with(cx_a, |buf, _| assert!(!buf.is_dirty()));
1668//         buffer_b.read_with(cx_b, |buf, _| assert!(!buf.is_dirty()));
1669//         buffer_c.condition(cx_c, |buf, _| !buf.is_dirty()).await;
1670
1671//         worktree_a.flush_fs_events(cx_a).await;
1672
1673//         // Make changes on host's file system, see those changes on guest worktrees.
1674//         fs.rename(
1675//             "/a/file1".as_ref(),
1676//             "/a/file1-renamed".as_ref(),
1677//             Default::default(),
1678//         )
1679//         .await
1680//         .unwrap();
1681
1682//         fs.rename("/a/file2".as_ref(), "/a/file3".as_ref(), Default::default())
1683//             .await
1684//             .unwrap();
1685//         fs.insert_file(Path::new("/a/file4"), "4".into()).await;
1686
1687//         worktree_a
1688//             .condition(&cx_a, |tree, _| {
1689//                 tree.paths()
1690//                     .map(|p| p.to_string_lossy())
1691//                     .collect::<Vec<_>>()
1692//                     == [".zed.toml", "file1-renamed", "file3", "file4"]
1693//             })
1694//             .await;
1695//         worktree_b
1696//             .condition(&cx_b, |tree, _| {
1697//                 tree.paths()
1698//                     .map(|p| p.to_string_lossy())
1699//                     .collect::<Vec<_>>()
1700//                     == [".zed.toml", "file1-renamed", "file3", "file4"]
1701//             })
1702//             .await;
1703//         worktree_c
1704//             .condition(&cx_c, |tree, _| {
1705//                 tree.paths()
1706//                     .map(|p| p.to_string_lossy())
1707//                     .collect::<Vec<_>>()
1708//                     == [".zed.toml", "file1-renamed", "file3", "file4"]
1709//             })
1710//             .await;
1711
1712//         // Ensure buffer files are updated as well.
1713//         buffer_a
1714//             .condition(&cx_a, |buf, _| {
1715//                 buf.file().unwrap().path().to_str() == Some("file1-renamed")
1716//             })
1717//             .await;
1718//         buffer_b
1719//             .condition(&cx_b, |buf, _| {
1720//                 buf.file().unwrap().path().to_str() == Some("file1-renamed")
1721//             })
1722//             .await;
1723//         buffer_c
1724//             .condition(&cx_c, |buf, _| {
1725//                 buf.file().unwrap().path().to_str() == Some("file1-renamed")
1726//             })
1727//             .await;
1728//     }
1729
1730//     #[gpui::test(iterations = 10)]
1731//     async fn test_buffer_conflict_after_save(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
1732//         cx_a.foreground().forbid_parking();
1733//         let lang_registry = Arc::new(LanguageRegistry::test());
1734//         let fs = FakeFs::new(cx_a.background());
1735
1736//         // Connect to a server as 2 clients.
1737//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1738//         let client_a = server.create_client(cx_a, "user_a").await;
1739//         let client_b = server.create_client(cx_b, "user_b").await;
1740
1741//         // Share a project as client A
1742//         fs.insert_tree(
1743//             "/dir",
1744//             json!({
1745//                 ".zed.toml": r#"collaborators = ["user_b", "user_c"]"#,
1746//                 "a.txt": "a-contents",
1747//             }),
1748//         )
1749//         .await;
1750
1751//         let project_a = cx_a.update(|cx| {
1752//             Project::local(
1753//                 client_a.clone(),
1754//                 client_a.user_store.clone(),
1755//                 lang_registry.clone(),
1756//                 fs.clone(),
1757//                 cx,
1758//             )
1759//         });
1760//         let (worktree_a, _) = project_a
1761//             .update(cx_a, |p, cx| {
1762//                 p.find_or_create_local_worktree("/dir", true, cx)
1763//             })
1764//             .await
1765//             .unwrap();
1766//         worktree_a
1767//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1768//             .await;
1769//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1770//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1771//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1772
1773//         // Join that project as client B
1774//         let project_b = Project::remote(
1775//             project_id,
1776//             client_b.clone(),
1777//             client_b.user_store.clone(),
1778//             lang_registry.clone(),
1779//             fs.clone(),
1780//             &mut cx_b.to_async(),
1781//         )
1782//         .await
1783//         .unwrap();
1784
1785//         // Open a buffer as client B
1786//         let buffer_b = project_b
1787//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1788//             .await
1789//             .unwrap();
1790
1791//         buffer_b.update(cx_b, |buf, cx| buf.edit([0..0], "world ", cx));
1792//         buffer_b.read_with(cx_b, |buf, _| {
1793//             assert!(buf.is_dirty());
1794//             assert!(!buf.has_conflict());
1795//         });
1796
1797//         buffer_b.update(cx_b, |buf, cx| buf.save(cx)).await.unwrap();
1798//         buffer_b
1799//             .condition(&cx_b, |buffer_b, _| !buffer_b.is_dirty())
1800//             .await;
1801//         buffer_b.read_with(cx_b, |buf, _| {
1802//             assert!(!buf.has_conflict());
1803//         });
1804
1805//         buffer_b.update(cx_b, |buf, cx| buf.edit([0..0], "hello ", cx));
1806//         buffer_b.read_with(cx_b, |buf, _| {
1807//             assert!(buf.is_dirty());
1808//             assert!(!buf.has_conflict());
1809//         });
1810//     }
1811
1812//     #[gpui::test(iterations = 10)]
1813//     async fn test_buffer_reloading(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
1814//         cx_a.foreground().forbid_parking();
1815//         let lang_registry = Arc::new(LanguageRegistry::test());
1816//         let fs = FakeFs::new(cx_a.background());
1817
1818//         // Connect to a server as 2 clients.
1819//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1820//         let client_a = server.create_client(cx_a, "user_a").await;
1821//         let client_b = server.create_client(cx_b, "user_b").await;
1822
1823//         // Share a project as client A
1824//         fs.insert_tree(
1825//             "/dir",
1826//             json!({
1827//                 ".zed.toml": r#"collaborators = ["user_b", "user_c"]"#,
1828//                 "a.txt": "a-contents",
1829//             }),
1830//         )
1831//         .await;
1832
1833//         let project_a = cx_a.update(|cx| {
1834//             Project::local(
1835//                 client_a.clone(),
1836//                 client_a.user_store.clone(),
1837//                 lang_registry.clone(),
1838//                 fs.clone(),
1839//                 cx,
1840//             )
1841//         });
1842//         let (worktree_a, _) = project_a
1843//             .update(cx_a, |p, cx| {
1844//                 p.find_or_create_local_worktree("/dir", true, cx)
1845//             })
1846//             .await
1847//             .unwrap();
1848//         worktree_a
1849//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1850//             .await;
1851//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1852//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1853//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1854
1855//         // Join that project as client B
1856//         let project_b = Project::remote(
1857//             project_id,
1858//             client_b.clone(),
1859//             client_b.user_store.clone(),
1860//             lang_registry.clone(),
1861//             fs.clone(),
1862//             &mut cx_b.to_async(),
1863//         )
1864//         .await
1865//         .unwrap();
1866//         let _worktree_b = project_b.update(cx_b, |p, cx| p.worktrees(cx).next().unwrap());
1867
1868//         // Open a buffer as client B
1869//         let buffer_b = project_b
1870//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1871//             .await
1872//             .unwrap();
1873//         buffer_b.read_with(cx_b, |buf, _| {
1874//             assert!(!buf.is_dirty());
1875//             assert!(!buf.has_conflict());
1876//         });
1877
1878//         fs.save(Path::new("/dir/a.txt"), &"new contents".into())
1879//             .await
1880//             .unwrap();
1881//         buffer_b
1882//             .condition(&cx_b, |buf, _| {
1883//                 buf.text() == "new contents" && !buf.is_dirty()
1884//             })
1885//             .await;
1886//         buffer_b.read_with(cx_b, |buf, _| {
1887//             assert!(!buf.has_conflict());
1888//         });
1889//     }
1890
1891//     #[gpui::test(iterations = 10)]
1892//     async fn test_editing_while_guest_opens_buffer(
1893//         cx_a: &mut TestAppContext,
1894//         cx_b: &mut TestAppContext,
1895//     ) {
1896//         cx_a.foreground().forbid_parking();
1897//         let lang_registry = Arc::new(LanguageRegistry::test());
1898//         let fs = FakeFs::new(cx_a.background());
1899
1900//         // Connect to a server as 2 clients.
1901//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1902//         let client_a = server.create_client(cx_a, "user_a").await;
1903//         let client_b = server.create_client(cx_b, "user_b").await;
1904
1905//         // Share a project as client A
1906//         fs.insert_tree(
1907//             "/dir",
1908//             json!({
1909//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
1910//                 "a.txt": "a-contents",
1911//             }),
1912//         )
1913//         .await;
1914//         let project_a = cx_a.update(|cx| {
1915//             Project::local(
1916//                 client_a.clone(),
1917//                 client_a.user_store.clone(),
1918//                 lang_registry.clone(),
1919//                 fs.clone(),
1920//                 cx,
1921//             )
1922//         });
1923//         let (worktree_a, _) = project_a
1924//             .update(cx_a, |p, cx| {
1925//                 p.find_or_create_local_worktree("/dir", true, cx)
1926//             })
1927//             .await
1928//             .unwrap();
1929//         worktree_a
1930//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
1931//             .await;
1932//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
1933//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
1934//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
1935
1936//         // Join that project as client B
1937//         let project_b = Project::remote(
1938//             project_id,
1939//             client_b.clone(),
1940//             client_b.user_store.clone(),
1941//             lang_registry.clone(),
1942//             fs.clone(),
1943//             &mut cx_b.to_async(),
1944//         )
1945//         .await
1946//         .unwrap();
1947
1948//         // Open a buffer as client A
1949//         let buffer_a = project_a
1950//             .update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
1951//             .await
1952//             .unwrap();
1953
1954//         // Start opening the same buffer as client B
1955//         let buffer_b = cx_b
1956//             .background()
1957//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx)));
1958
1959//         // Edit the buffer as client A while client B is still opening it.
1960//         cx_b.background().simulate_random_delay().await;
1961//         buffer_a.update(cx_a, |buf, cx| buf.edit([0..0], "X", cx));
1962//         cx_b.background().simulate_random_delay().await;
1963//         buffer_a.update(cx_a, |buf, cx| buf.edit([1..1], "Y", cx));
1964
1965//         let text = buffer_a.read_with(cx_a, |buf, _| buf.text());
1966//         let buffer_b = buffer_b.await.unwrap();
1967//         buffer_b.condition(&cx_b, |buf, _| buf.text() == text).await;
1968//     }
1969
1970//     #[gpui::test(iterations = 10)]
1971//     async fn test_leaving_worktree_while_opening_buffer(
1972//         cx_a: &mut TestAppContext,
1973//         cx_b: &mut TestAppContext,
1974//     ) {
1975//         cx_a.foreground().forbid_parking();
1976//         let lang_registry = Arc::new(LanguageRegistry::test());
1977//         let fs = FakeFs::new(cx_a.background());
1978
1979//         // Connect to a server as 2 clients.
1980//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
1981//         let client_a = server.create_client(cx_a, "user_a").await;
1982//         let client_b = server.create_client(cx_b, "user_b").await;
1983
1984//         // Share a project as client A
1985//         fs.insert_tree(
1986//             "/dir",
1987//             json!({
1988//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
1989//                 "a.txt": "a-contents",
1990//             }),
1991//         )
1992//         .await;
1993//         let project_a = cx_a.update(|cx| {
1994//             Project::local(
1995//                 client_a.clone(),
1996//                 client_a.user_store.clone(),
1997//                 lang_registry.clone(),
1998//                 fs.clone(),
1999//                 cx,
2000//             )
2001//         });
2002//         let (worktree_a, _) = project_a
2003//             .update(cx_a, |p, cx| {
2004//                 p.find_or_create_local_worktree("/dir", true, cx)
2005//             })
2006//             .await
2007//             .unwrap();
2008//         worktree_a
2009//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2010//             .await;
2011//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
2012//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
2013//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
2014
2015//         // Join that project as client B
2016//         let project_b = Project::remote(
2017//             project_id,
2018//             client_b.clone(),
2019//             client_b.user_store.clone(),
2020//             lang_registry.clone(),
2021//             fs.clone(),
2022//             &mut cx_b.to_async(),
2023//         )
2024//         .await
2025//         .unwrap();
2026
2027//         // See that a guest has joined as client A.
2028//         project_a
2029//             .condition(&cx_a, |p, _| p.collaborators().len() == 1)
2030//             .await;
2031
2032//         // Begin opening a buffer as client B, but leave the project before the open completes.
2033//         let buffer_b = cx_b
2034//             .background()
2035//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx)));
2036//         cx_b.update(|_| drop(project_b));
2037//         drop(buffer_b);
2038
2039//         // See that the guest has left.
2040//         project_a
2041//             .condition(&cx_a, |p, _| p.collaborators().len() == 0)
2042//             .await;
2043//     }
2044
2045//     #[gpui::test(iterations = 10)]
2046//     async fn test_leaving_project(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
2047//         cx_a.foreground().forbid_parking();
2048//         let lang_registry = Arc::new(LanguageRegistry::test());
2049//         let fs = FakeFs::new(cx_a.background());
2050
2051//         // Connect to a server as 2 clients.
2052//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2053//         let client_a = server.create_client(cx_a, "user_a").await;
2054//         let client_b = server.create_client(cx_b, "user_b").await;
2055
2056//         // Share a project as client A
2057//         fs.insert_tree(
2058//             "/a",
2059//             json!({
2060//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2061//                 "a.txt": "a-contents",
2062//                 "b.txt": "b-contents",
2063//             }),
2064//         )
2065//         .await;
2066//         let project_a = cx_a.update(|cx| {
2067//             Project::local(
2068//                 client_a.clone(),
2069//                 client_a.user_store.clone(),
2070//                 lang_registry.clone(),
2071//                 fs.clone(),
2072//                 cx,
2073//             )
2074//         });
2075//         let (worktree_a, _) = project_a
2076//             .update(cx_a, |p, cx| {
2077//                 p.find_or_create_local_worktree("/a", true, cx)
2078//             })
2079//             .await
2080//             .unwrap();
2081//         worktree_a
2082//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2083//             .await;
2084//         let project_id = project_a
2085//             .update(cx_a, |project, _| project.next_remote_id())
2086//             .await;
2087//         project_a
2088//             .update(cx_a, |project, cx| project.share(cx))
2089//             .await
2090//             .unwrap();
2091
2092//         // Join that project as client B
2093//         let _project_b = Project::remote(
2094//             project_id,
2095//             client_b.clone(),
2096//             client_b.user_store.clone(),
2097//             lang_registry.clone(),
2098//             fs.clone(),
2099//             &mut cx_b.to_async(),
2100//         )
2101//         .await
2102//         .unwrap();
2103
2104//         // Client A sees that a guest has joined.
2105//         project_a
2106//             .condition(cx_a, |p, _| p.collaborators().len() == 1)
2107//             .await;
2108
2109//         // Drop client B's connection and ensure client A observes client B leaving the project.
2110//         client_b.disconnect(&cx_b.to_async()).unwrap();
2111//         project_a
2112//             .condition(cx_a, |p, _| p.collaborators().len() == 0)
2113//             .await;
2114
2115//         // Rejoin the project as client B
2116//         let _project_b = Project::remote(
2117//             project_id,
2118//             client_b.clone(),
2119//             client_b.user_store.clone(),
2120//             lang_registry.clone(),
2121//             fs.clone(),
2122//             &mut cx_b.to_async(),
2123//         )
2124//         .await
2125//         .unwrap();
2126
2127//         // Client A sees that a guest has re-joined.
2128//         project_a
2129//             .condition(cx_a, |p, _| p.collaborators().len() == 1)
2130//             .await;
2131
2132//         // Simulate connection loss for client B and ensure client A observes client B leaving the project.
2133//         client_b.wait_for_current_user(cx_b).await;
2134//         server.disconnect_client(client_b.current_user_id(cx_b));
2135//         cx_a.foreground().advance_clock(Duration::from_secs(3));
2136//         project_a
2137//             .condition(cx_a, |p, _| p.collaborators().len() == 0)
2138//             .await;
2139//     }
2140
2141//     #[gpui::test(iterations = 10)]
2142//     async fn test_collaborating_with_diagnostics(
2143//         cx_a: &mut TestAppContext,
2144//         cx_b: &mut TestAppContext,
2145//     ) {
2146//         cx_a.foreground().forbid_parking();
2147//         let lang_registry = Arc::new(LanguageRegistry::test());
2148//         let fs = FakeFs::new(cx_a.background());
2149
2150//         // Set up a fake language server.
2151//         let mut language = Language::new(
2152//             LanguageConfig {
2153//                 name: "Rust".into(),
2154//                 path_suffixes: vec!["rs".to_string()],
2155//                 ..Default::default()
2156//             },
2157//             Some(tree_sitter_rust::language()),
2158//         );
2159//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
2160//         lang_registry.add(Arc::new(language));
2161
2162//         // Connect to a server as 2 clients.
2163//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2164//         let client_a = server.create_client(cx_a, "user_a").await;
2165//         let client_b = server.create_client(cx_b, "user_b").await;
2166
2167//         // Share a project as client A
2168//         fs.insert_tree(
2169//             "/a",
2170//             json!({
2171//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2172//                 "a.rs": "let one = two",
2173//                 "other.rs": "",
2174//             }),
2175//         )
2176//         .await;
2177//         let project_a = cx_a.update(|cx| {
2178//             Project::local(
2179//                 client_a.clone(),
2180//                 client_a.user_store.clone(),
2181//                 lang_registry.clone(),
2182//                 fs.clone(),
2183//                 cx,
2184//             )
2185//         });
2186//         let (worktree_a, _) = project_a
2187//             .update(cx_a, |p, cx| {
2188//                 p.find_or_create_local_worktree("/a", true, cx)
2189//             })
2190//             .await
2191//             .unwrap();
2192//         worktree_a
2193//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2194//             .await;
2195//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
2196//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
2197//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
2198
2199//         // Cause the language server to start.
2200//         let _ = cx_a
2201//             .background()
2202//             .spawn(project_a.update(cx_a, |project, cx| {
2203//                 project.open_buffer(
2204//                     ProjectPath {
2205//                         worktree_id,
2206//                         path: Path::new("other.rs").into(),
2207//                     },
2208//                     cx,
2209//                 )
2210//             }))
2211//             .await
2212//             .unwrap();
2213
2214//         // Simulate a language server reporting errors for a file.
2215//         let mut fake_language_server = fake_language_servers.next().await.unwrap();
2216//         fake_language_server
2217//             .receive_notification::<lsp::notification::DidOpenTextDocument>()
2218//             .await;
2219//         fake_language_server.notify::<lsp::notification::PublishDiagnostics>(
2220//             lsp::PublishDiagnosticsParams {
2221//                 uri: lsp::Url::from_file_path("/a/a.rs").unwrap(),
2222//                 version: None,
2223//                 diagnostics: vec![lsp::Diagnostic {
2224//                     severity: Some(lsp::DiagnosticSeverity::ERROR),
2225//                     range: lsp::Range::new(lsp::Position::new(0, 4), lsp::Position::new(0, 7)),
2226//                     message: "message 1".to_string(),
2227//                     ..Default::default()
2228//                 }],
2229//             },
2230//         );
2231
2232//         // Wait for server to see the diagnostics update.
2233//         server
2234//             .condition(|store| {
2235//                 let worktree = store
2236//                     .project(project_id)
2237//                     .unwrap()
2238//                     .share
2239//                     .as_ref()
2240//                     .unwrap()
2241//                     .worktrees
2242//                     .get(&worktree_id.to_proto())
2243//                     .unwrap();
2244
2245//                 !worktree.diagnostic_summaries.is_empty()
2246//             })
2247//             .await;
2248
2249//         // Join the worktree as client B.
2250//         let project_b = Project::remote(
2251//             project_id,
2252//             client_b.clone(),
2253//             client_b.user_store.clone(),
2254//             lang_registry.clone(),
2255//             fs.clone(),
2256//             &mut cx_b.to_async(),
2257//         )
2258//         .await
2259//         .unwrap();
2260
2261//         project_b.read_with(cx_b, |project, cx| {
2262//             assert_eq!(
2263//                 project.diagnostic_summaries(cx).collect::<Vec<_>>(),
2264//                 &[(
2265//                     ProjectPath {
2266//                         worktree_id,
2267//                         path: Arc::from(Path::new("a.rs")),
2268//                     },
2269//                     DiagnosticSummary {
2270//                         error_count: 1,
2271//                         warning_count: 0,
2272//                         ..Default::default()
2273//                     },
2274//                 )]
2275//             )
2276//         });
2277
2278//         // Simulate a language server reporting more errors for a file.
2279//         fake_language_server.notify::<lsp::notification::PublishDiagnostics>(
2280//             lsp::PublishDiagnosticsParams {
2281//                 uri: lsp::Url::from_file_path("/a/a.rs").unwrap(),
2282//                 version: None,
2283//                 diagnostics: vec![
2284//                     lsp::Diagnostic {
2285//                         severity: Some(lsp::DiagnosticSeverity::ERROR),
2286//                         range: lsp::Range::new(lsp::Position::new(0, 4), lsp::Position::new(0, 7)),
2287//                         message: "message 1".to_string(),
2288//                         ..Default::default()
2289//                     },
2290//                     lsp::Diagnostic {
2291//                         severity: Some(lsp::DiagnosticSeverity::WARNING),
2292//                         range: lsp::Range::new(
2293//                             lsp::Position::new(0, 10),
2294//                             lsp::Position::new(0, 13),
2295//                         ),
2296//                         message: "message 2".to_string(),
2297//                         ..Default::default()
2298//                     },
2299//                 ],
2300//             },
2301//         );
2302
2303//         // Client b gets the updated summaries
2304//         project_b
2305//             .condition(&cx_b, |project, cx| {
2306//                 project.diagnostic_summaries(cx).collect::<Vec<_>>()
2307//                     == &[(
2308//                         ProjectPath {
2309//                             worktree_id,
2310//                             path: Arc::from(Path::new("a.rs")),
2311//                         },
2312//                         DiagnosticSummary {
2313//                             error_count: 1,
2314//                             warning_count: 1,
2315//                             ..Default::default()
2316//                         },
2317//                     )]
2318//             })
2319//             .await;
2320
2321//         // Open the file with the errors on client B. They should be present.
2322//         let buffer_b = cx_b
2323//             .background()
2324//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)))
2325//             .await
2326//             .unwrap();
2327
2328//         buffer_b.read_with(cx_b, |buffer, _| {
2329//             assert_eq!(
2330//                 buffer
2331//                     .snapshot()
2332//                     .diagnostics_in_range::<_, Point>(0..buffer.len(), false)
2333//                     .map(|entry| entry)
2334//                     .collect::<Vec<_>>(),
2335//                 &[
2336//                     DiagnosticEntry {
2337//                         range: Point::new(0, 4)..Point::new(0, 7),
2338//                         diagnostic: Diagnostic {
2339//                             group_id: 0,
2340//                             message: "message 1".to_string(),
2341//                             severity: lsp::DiagnosticSeverity::ERROR,
2342//                             is_primary: true,
2343//                             ..Default::default()
2344//                         }
2345//                     },
2346//                     DiagnosticEntry {
2347//                         range: Point::new(0, 10)..Point::new(0, 13),
2348//                         diagnostic: Diagnostic {
2349//                             group_id: 1,
2350//                             severity: lsp::DiagnosticSeverity::WARNING,
2351//                             message: "message 2".to_string(),
2352//                             is_primary: true,
2353//                             ..Default::default()
2354//                         }
2355//                     }
2356//                 ]
2357//             );
2358//         });
2359
2360//         // Simulate a language server reporting no errors for a file.
2361//         fake_language_server.notify::<lsp::notification::PublishDiagnostics>(
2362//             lsp::PublishDiagnosticsParams {
2363//                 uri: lsp::Url::from_file_path("/a/a.rs").unwrap(),
2364//                 version: None,
2365//                 diagnostics: vec![],
2366//             },
2367//         );
2368//         project_a
2369//             .condition(cx_a, |project, cx| {
2370//                 project.diagnostic_summaries(cx).collect::<Vec<_>>() == &[]
2371//             })
2372//             .await;
2373//         project_b
2374//             .condition(cx_b, |project, cx| {
2375//                 project.diagnostic_summaries(cx).collect::<Vec<_>>() == &[]
2376//             })
2377//             .await;
2378//     }
2379
2380//     #[gpui::test(iterations = 10)]
2381//     async fn test_collaborating_with_completion(
2382//         cx_a: &mut TestAppContext,
2383//         cx_b: &mut TestAppContext,
2384//     ) {
2385//         cx_a.foreground().forbid_parking();
2386//         let lang_registry = Arc::new(LanguageRegistry::test());
2387//         let fs = FakeFs::new(cx_a.background());
2388
2389//         // Set up a fake language server.
2390//         let mut language = Language::new(
2391//             LanguageConfig {
2392//                 name: "Rust".into(),
2393//                 path_suffixes: vec!["rs".to_string()],
2394//                 ..Default::default()
2395//             },
2396//             Some(tree_sitter_rust::language()),
2397//         );
2398//         let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
2399//             capabilities: lsp::ServerCapabilities {
2400//                 completion_provider: Some(lsp::CompletionOptions {
2401//                     trigger_characters: Some(vec![".".to_string()]),
2402//                     ..Default::default()
2403//                 }),
2404//                 ..Default::default()
2405//             },
2406//             ..Default::default()
2407//         });
2408//         lang_registry.add(Arc::new(language));
2409
2410//         // Connect to a server as 2 clients.
2411//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2412//         let client_a = server.create_client(cx_a, "user_a").await;
2413//         let client_b = server.create_client(cx_b, "user_b").await;
2414
2415//         // Share a project as client A
2416//         fs.insert_tree(
2417//             "/a",
2418//             json!({
2419//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2420//                 "main.rs": "fn main() { a }",
2421//                 "other.rs": "",
2422//             }),
2423//         )
2424//         .await;
2425//         let project_a = cx_a.update(|cx| {
2426//             Project::local(
2427//                 client_a.clone(),
2428//                 client_a.user_store.clone(),
2429//                 lang_registry.clone(),
2430//                 fs.clone(),
2431//                 cx,
2432//             )
2433//         });
2434//         let (worktree_a, _) = project_a
2435//             .update(cx_a, |p, cx| {
2436//                 p.find_or_create_local_worktree("/a", true, cx)
2437//             })
2438//             .await
2439//             .unwrap();
2440//         worktree_a
2441//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2442//             .await;
2443//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
2444//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
2445//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
2446
2447//         // Join the worktree as client B.
2448//         let project_b = Project::remote(
2449//             project_id,
2450//             client_b.clone(),
2451//             client_b.user_store.clone(),
2452//             lang_registry.clone(),
2453//             fs.clone(),
2454//             &mut cx_b.to_async(),
2455//         )
2456//         .await
2457//         .unwrap();
2458
2459//         // Open a file in an editor as the guest.
2460//         let buffer_b = project_b
2461//             .update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx))
2462//             .await
2463//             .unwrap();
2464//         let (window_b, _) = cx_b.add_window(|_| EmptyView);
2465//         let editor_b = cx_b.add_view(window_b, |cx| {
2466//             Editor::for_buffer(buffer_b.clone(), Some(project_b.clone()), cx)
2467//         });
2468
2469//         let fake_language_server = fake_language_servers.next().await.unwrap();
2470//         buffer_b
2471//             .condition(&cx_b, |buffer, _| !buffer.completion_triggers().is_empty())
2472//             .await;
2473
2474//         // Type a completion trigger character as the guest.
2475//         editor_b.update(cx_b, |editor, cx| {
2476//             editor.select_ranges([13..13], None, cx);
2477//             editor.handle_input(&Input(".".into()), cx);
2478//             cx.focus(&editor_b);
2479//         });
2480
2481//         // Receive a completion request as the host's language server.
2482//         // Return some completions from the host's language server.
2483//         cx_a.foreground().start_waiting();
2484//         fake_language_server
2485//             .handle_request::<lsp::request::Completion, _, _>(|params, _| async move {
2486//                 assert_eq!(
2487//                     params.text_document_position.text_document.uri,
2488//                     lsp::Url::from_file_path("/a/main.rs").unwrap(),
2489//                 );
2490//                 assert_eq!(
2491//                     params.text_document_position.position,
2492//                     lsp::Position::new(0, 14),
2493//                 );
2494
2495//                 Ok(Some(lsp::CompletionResponse::Array(vec![
2496//                     lsp::CompletionItem {
2497//                         label: "first_method(…)".into(),
2498//                         detail: Some("fn(&mut self, B) -> C".into()),
2499//                         text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
2500//                             new_text: "first_method($1)".to_string(),
2501//                             range: lsp::Range::new(
2502//                                 lsp::Position::new(0, 14),
2503//                                 lsp::Position::new(0, 14),
2504//                             ),
2505//                         })),
2506//                         insert_text_format: Some(lsp::InsertTextFormat::SNIPPET),
2507//                         ..Default::default()
2508//                     },
2509//                     lsp::CompletionItem {
2510//                         label: "second_method(…)".into(),
2511//                         detail: Some("fn(&mut self, C) -> D<E>".into()),
2512//                         text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
2513//                             new_text: "second_method()".to_string(),
2514//                             range: lsp::Range::new(
2515//                                 lsp::Position::new(0, 14),
2516//                                 lsp::Position::new(0, 14),
2517//                             ),
2518//                         })),
2519//                         insert_text_format: Some(lsp::InsertTextFormat::SNIPPET),
2520//                         ..Default::default()
2521//                     },
2522//                 ])))
2523//             })
2524//             .next()
2525//             .await
2526//             .unwrap();
2527//         cx_a.foreground().finish_waiting();
2528
2529//         // Open the buffer on the host.
2530//         let buffer_a = project_a
2531//             .update(cx_a, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx))
2532//             .await
2533//             .unwrap();
2534//         buffer_a
2535//             .condition(&cx_a, |buffer, _| buffer.text() == "fn main() { a. }")
2536//             .await;
2537
2538//         // Confirm a completion on the guest.
2539//         editor_b
2540//             .condition(&cx_b, |editor, _| editor.context_menu_visible())
2541//             .await;
2542//         editor_b.update(cx_b, |editor, cx| {
2543//             editor.confirm_completion(&ConfirmCompletion { item_ix: Some(0) }, cx);
2544//             assert_eq!(editor.text(cx), "fn main() { a.first_method() }");
2545//         });
2546
2547//         // Return a resolved completion from the host's language server.
2548//         // The resolved completion has an additional text edit.
2549//         fake_language_server.handle_request::<lsp::request::ResolveCompletionItem, _, _>(
2550//             |params, _| async move {
2551//                 assert_eq!(params.label, "first_method(…)");
2552//                 Ok(lsp::CompletionItem {
2553//                     label: "first_method(…)".into(),
2554//                     detail: Some("fn(&mut self, B) -> C".into()),
2555//                     text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
2556//                         new_text: "first_method($1)".to_string(),
2557//                         range: lsp::Range::new(
2558//                             lsp::Position::new(0, 14),
2559//                             lsp::Position::new(0, 14),
2560//                         ),
2561//                     })),
2562//                     additional_text_edits: Some(vec![lsp::TextEdit {
2563//                         new_text: "use d::SomeTrait;\n".to_string(),
2564//                         range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 0)),
2565//                     }]),
2566//                     insert_text_format: Some(lsp::InsertTextFormat::SNIPPET),
2567//                     ..Default::default()
2568//                 })
2569//             },
2570//         );
2571
2572//         // The additional edit is applied.
2573//         buffer_a
2574//             .condition(&cx_a, |buffer, _| {
2575//                 buffer.text() == "use d::SomeTrait;\nfn main() { a.first_method() }"
2576//             })
2577//             .await;
2578//         buffer_b
2579//             .condition(&cx_b, |buffer, _| {
2580//                 buffer.text() == "use d::SomeTrait;\nfn main() { a.first_method() }"
2581//             })
2582//             .await;
2583//     }
2584
2585//     #[gpui::test(iterations = 10)]
2586//     async fn test_reloading_buffer_manually(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
2587//         cx_a.foreground().forbid_parking();
2588//         let lang_registry = Arc::new(LanguageRegistry::test());
2589//         let fs = FakeFs::new(cx_a.background());
2590
2591//         // Connect to a server as 2 clients.
2592//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2593//         let client_a = server.create_client(cx_a, "user_a").await;
2594//         let client_b = server.create_client(cx_b, "user_b").await;
2595
2596//         // Share a project as client A
2597//         fs.insert_tree(
2598//             "/a",
2599//             json!({
2600//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2601//                 "a.rs": "let one = 1;",
2602//             }),
2603//         )
2604//         .await;
2605//         let project_a = cx_a.update(|cx| {
2606//             Project::local(
2607//                 client_a.clone(),
2608//                 client_a.user_store.clone(),
2609//                 lang_registry.clone(),
2610//                 fs.clone(),
2611//                 cx,
2612//             )
2613//         });
2614//         let (worktree_a, _) = project_a
2615//             .update(cx_a, |p, cx| {
2616//                 p.find_or_create_local_worktree("/a", true, cx)
2617//             })
2618//             .await
2619//             .unwrap();
2620//         worktree_a
2621//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2622//             .await;
2623//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
2624//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
2625//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
2626//         let buffer_a = project_a
2627//             .update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx))
2628//             .await
2629//             .unwrap();
2630
2631//         // Join the worktree as client B.
2632//         let project_b = Project::remote(
2633//             project_id,
2634//             client_b.clone(),
2635//             client_b.user_store.clone(),
2636//             lang_registry.clone(),
2637//             fs.clone(),
2638//             &mut cx_b.to_async(),
2639//         )
2640//         .await
2641//         .unwrap();
2642
2643//         let buffer_b = cx_b
2644//             .background()
2645//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)))
2646//             .await
2647//             .unwrap();
2648//         buffer_b.update(cx_b, |buffer, cx| {
2649//             buffer.edit([4..7], "six", cx);
2650//             buffer.edit([10..11], "6", cx);
2651//             assert_eq!(buffer.text(), "let six = 6;");
2652//             assert!(buffer.is_dirty());
2653//             assert!(!buffer.has_conflict());
2654//         });
2655//         buffer_a
2656//             .condition(cx_a, |buffer, _| buffer.text() == "let six = 6;")
2657//             .await;
2658
2659//         fs.save(Path::new("/a/a.rs"), &Rope::from("let seven = 7;"))
2660//             .await
2661//             .unwrap();
2662//         buffer_a
2663//             .condition(cx_a, |buffer, _| buffer.has_conflict())
2664//             .await;
2665//         buffer_b
2666//             .condition(cx_b, |buffer, _| buffer.has_conflict())
2667//             .await;
2668
2669//         project_b
2670//             .update(cx_b, |project, cx| {
2671//                 project.reload_buffers(HashSet::from_iter([buffer_b.clone()]), true, cx)
2672//             })
2673//             .await
2674//             .unwrap();
2675//         buffer_a.read_with(cx_a, |buffer, _| {
2676//             assert_eq!(buffer.text(), "let seven = 7;");
2677//             assert!(!buffer.is_dirty());
2678//             assert!(!buffer.has_conflict());
2679//         });
2680//         buffer_b.read_with(cx_b, |buffer, _| {
2681//             assert_eq!(buffer.text(), "let seven = 7;");
2682//             assert!(!buffer.is_dirty());
2683//             assert!(!buffer.has_conflict());
2684//         });
2685
2686//         buffer_a.update(cx_a, |buffer, cx| {
2687//             // Undoing on the host is a no-op when the reload was initiated by the guest.
2688//             buffer.undo(cx);
2689//             assert_eq!(buffer.text(), "let seven = 7;");
2690//             assert!(!buffer.is_dirty());
2691//             assert!(!buffer.has_conflict());
2692//         });
2693//         buffer_b.update(cx_b, |buffer, cx| {
2694//             // Undoing on the guest rolls back the buffer to before it was reloaded but the conflict gets cleared.
2695//             buffer.undo(cx);
2696//             assert_eq!(buffer.text(), "let six = 6;");
2697//             assert!(buffer.is_dirty());
2698//             assert!(!buffer.has_conflict());
2699//         });
2700//     }
2701
2702//     #[gpui::test(iterations = 10)]
2703//     async fn test_formatting_buffer(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
2704//         cx_a.foreground().forbid_parking();
2705//         let lang_registry = Arc::new(LanguageRegistry::test());
2706//         let fs = FakeFs::new(cx_a.background());
2707
2708//         // Set up a fake language server.
2709//         let mut language = Language::new(
2710//             LanguageConfig {
2711//                 name: "Rust".into(),
2712//                 path_suffixes: vec!["rs".to_string()],
2713//                 ..Default::default()
2714//             },
2715//             Some(tree_sitter_rust::language()),
2716//         );
2717//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
2718//         lang_registry.add(Arc::new(language));
2719
2720//         // Connect to a server as 2 clients.
2721//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2722//         let client_a = server.create_client(cx_a, "user_a").await;
2723//         let client_b = server.create_client(cx_b, "user_b").await;
2724
2725//         // Share a project as client A
2726//         fs.insert_tree(
2727//             "/a",
2728//             json!({
2729//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2730//                 "a.rs": "let one = two",
2731//             }),
2732//         )
2733//         .await;
2734//         let project_a = cx_a.update(|cx| {
2735//             Project::local(
2736//                 client_a.clone(),
2737//                 client_a.user_store.clone(),
2738//                 lang_registry.clone(),
2739//                 fs.clone(),
2740//                 cx,
2741//             )
2742//         });
2743//         let (worktree_a, _) = project_a
2744//             .update(cx_a, |p, cx| {
2745//                 p.find_or_create_local_worktree("/a", true, cx)
2746//             })
2747//             .await
2748//             .unwrap();
2749//         worktree_a
2750//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2751//             .await;
2752//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
2753//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
2754//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
2755
2756//         // Join the worktree as client B.
2757//         let project_b = Project::remote(
2758//             project_id,
2759//             client_b.clone(),
2760//             client_b.user_store.clone(),
2761//             lang_registry.clone(),
2762//             fs.clone(),
2763//             &mut cx_b.to_async(),
2764//         )
2765//         .await
2766//         .unwrap();
2767
2768//         let buffer_b = cx_b
2769//             .background()
2770//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)))
2771//             .await
2772//             .unwrap();
2773
2774//         let fake_language_server = fake_language_servers.next().await.unwrap();
2775//         fake_language_server.handle_request::<lsp::request::Formatting, _, _>(|_, _| async move {
2776//             Ok(Some(vec![
2777//                 lsp::TextEdit {
2778//                     range: lsp::Range::new(lsp::Position::new(0, 4), lsp::Position::new(0, 4)),
2779//                     new_text: "h".to_string(),
2780//                 },
2781//                 lsp::TextEdit {
2782//                     range: lsp::Range::new(lsp::Position::new(0, 7), lsp::Position::new(0, 7)),
2783//                     new_text: "y".to_string(),
2784//                 },
2785//             ]))
2786//         });
2787
2788//         project_b
2789//             .update(cx_b, |project, cx| {
2790//                 project.format(HashSet::from_iter([buffer_b.clone()]), true, cx)
2791//             })
2792//             .await
2793//             .unwrap();
2794//         assert_eq!(
2795//             buffer_b.read_with(cx_b, |buffer, _| buffer.text()),
2796//             "let honey = two"
2797//         );
2798//     }
2799
2800//     #[gpui::test(iterations = 10)]
2801//     async fn test_definition(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
2802//         cx_a.foreground().forbid_parking();
2803//         let lang_registry = Arc::new(LanguageRegistry::test());
2804//         let fs = FakeFs::new(cx_a.background());
2805//         fs.insert_tree(
2806//             "/root-1",
2807//             json!({
2808//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2809//                 "a.rs": "const ONE: usize = b::TWO + b::THREE;",
2810//             }),
2811//         )
2812//         .await;
2813//         fs.insert_tree(
2814//             "/root-2",
2815//             json!({
2816//                 "b.rs": "const TWO: usize = 2;\nconst THREE: usize = 3;",
2817//             }),
2818//         )
2819//         .await;
2820
2821//         // Set up a fake language server.
2822//         let mut language = Language::new(
2823//             LanguageConfig {
2824//                 name: "Rust".into(),
2825//                 path_suffixes: vec!["rs".to_string()],
2826//                 ..Default::default()
2827//             },
2828//             Some(tree_sitter_rust::language()),
2829//         );
2830//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
2831//         lang_registry.add(Arc::new(language));
2832
2833//         // Connect to a server as 2 clients.
2834//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2835//         let client_a = server.create_client(cx_a, "user_a").await;
2836//         let client_b = server.create_client(cx_b, "user_b").await;
2837
2838//         // Share a project as client A
2839//         let project_a = cx_a.update(|cx| {
2840//             Project::local(
2841//                 client_a.clone(),
2842//                 client_a.user_store.clone(),
2843//                 lang_registry.clone(),
2844//                 fs.clone(),
2845//                 cx,
2846//             )
2847//         });
2848//         let (worktree_a, _) = project_a
2849//             .update(cx_a, |p, cx| {
2850//                 p.find_or_create_local_worktree("/root-1", true, cx)
2851//             })
2852//             .await
2853//             .unwrap();
2854//         worktree_a
2855//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
2856//             .await;
2857//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
2858//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
2859//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
2860
2861//         // Join the worktree as client B.
2862//         let project_b = Project::remote(
2863//             project_id,
2864//             client_b.clone(),
2865//             client_b.user_store.clone(),
2866//             lang_registry.clone(),
2867//             fs.clone(),
2868//             &mut cx_b.to_async(),
2869//         )
2870//         .await
2871//         .unwrap();
2872
2873//         // Open the file on client B.
2874//         let buffer_b = cx_b
2875//             .background()
2876//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)))
2877//             .await
2878//             .unwrap();
2879
2880//         // Request the definition of a symbol as the guest.
2881//         let fake_language_server = fake_language_servers.next().await.unwrap();
2882//         fake_language_server.handle_request::<lsp::request::GotoDefinition, _, _>(
2883//             |_, _| async move {
2884//                 Ok(Some(lsp::GotoDefinitionResponse::Scalar(
2885//                     lsp::Location::new(
2886//                         lsp::Url::from_file_path("/root-2/b.rs").unwrap(),
2887//                         lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)),
2888//                     ),
2889//                 )))
2890//             },
2891//         );
2892
2893//         let definitions_1 = project_b
2894//             .update(cx_b, |p, cx| p.definition(&buffer_b, 23, cx))
2895//             .await
2896//             .unwrap();
2897//         cx_b.read(|cx| {
2898//             assert_eq!(definitions_1.len(), 1);
2899//             assert_eq!(project_b.read(cx).worktrees(cx).count(), 2);
2900//             let target_buffer = definitions_1[0].buffer.read(cx);
2901//             assert_eq!(
2902//                 target_buffer.text(),
2903//                 "const TWO: usize = 2;\nconst THREE: usize = 3;"
2904//             );
2905//             assert_eq!(
2906//                 definitions_1[0].range.to_point(target_buffer),
2907//                 Point::new(0, 6)..Point::new(0, 9)
2908//             );
2909//         });
2910
2911//         // Try getting more definitions for the same buffer, ensuring the buffer gets reused from
2912//         // the previous call to `definition`.
2913//         fake_language_server.handle_request::<lsp::request::GotoDefinition, _, _>(
2914//             |_, _| async move {
2915//                 Ok(Some(lsp::GotoDefinitionResponse::Scalar(
2916//                     lsp::Location::new(
2917//                         lsp::Url::from_file_path("/root-2/b.rs").unwrap(),
2918//                         lsp::Range::new(lsp::Position::new(1, 6), lsp::Position::new(1, 11)),
2919//                     ),
2920//                 )))
2921//             },
2922//         );
2923
2924//         let definitions_2 = project_b
2925//             .update(cx_b, |p, cx| p.definition(&buffer_b, 33, cx))
2926//             .await
2927//             .unwrap();
2928//         cx_b.read(|cx| {
2929//             assert_eq!(definitions_2.len(), 1);
2930//             assert_eq!(project_b.read(cx).worktrees(cx).count(), 2);
2931//             let target_buffer = definitions_2[0].buffer.read(cx);
2932//             assert_eq!(
2933//                 target_buffer.text(),
2934//                 "const TWO: usize = 2;\nconst THREE: usize = 3;"
2935//             );
2936//             assert_eq!(
2937//                 definitions_2[0].range.to_point(target_buffer),
2938//                 Point::new(1, 6)..Point::new(1, 11)
2939//             );
2940//         });
2941//         assert_eq!(definitions_1[0].buffer, definitions_2[0].buffer);
2942//     }
2943
2944//     #[gpui::test(iterations = 10)]
2945//     async fn test_references(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
2946//         cx_a.foreground().forbid_parking();
2947//         let lang_registry = Arc::new(LanguageRegistry::test());
2948//         let fs = FakeFs::new(cx_a.background());
2949//         fs.insert_tree(
2950//             "/root-1",
2951//             json!({
2952//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
2953//                 "one.rs": "const ONE: usize = 1;",
2954//                 "two.rs": "const TWO: usize = one::ONE + one::ONE;",
2955//             }),
2956//         )
2957//         .await;
2958//         fs.insert_tree(
2959//             "/root-2",
2960//             json!({
2961//                 "three.rs": "const THREE: usize = two::TWO + one::ONE;",
2962//             }),
2963//         )
2964//         .await;
2965
2966//         // Set up a fake language server.
2967//         let mut language = Language::new(
2968//             LanguageConfig {
2969//                 name: "Rust".into(),
2970//                 path_suffixes: vec!["rs".to_string()],
2971//                 ..Default::default()
2972//             },
2973//             Some(tree_sitter_rust::language()),
2974//         );
2975//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
2976//         lang_registry.add(Arc::new(language));
2977
2978//         // Connect to a server as 2 clients.
2979//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
2980//         let client_a = server.create_client(cx_a, "user_a").await;
2981//         let client_b = server.create_client(cx_b, "user_b").await;
2982
2983//         // Share a project as client A
2984//         let project_a = cx_a.update(|cx| {
2985//             Project::local(
2986//                 client_a.clone(),
2987//                 client_a.user_store.clone(),
2988//                 lang_registry.clone(),
2989//                 fs.clone(),
2990//                 cx,
2991//             )
2992//         });
2993//         let (worktree_a, _) = project_a
2994//             .update(cx_a, |p, cx| {
2995//                 p.find_or_create_local_worktree("/root-1", true, cx)
2996//             })
2997//             .await
2998//             .unwrap();
2999//         worktree_a
3000//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3001//             .await;
3002//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3003//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
3004//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3005
3006//         // Join the worktree as client B.
3007//         let project_b = Project::remote(
3008//             project_id,
3009//             client_b.clone(),
3010//             client_b.user_store.clone(),
3011//             lang_registry.clone(),
3012//             fs.clone(),
3013//             &mut cx_b.to_async(),
3014//         )
3015//         .await
3016//         .unwrap();
3017
3018//         // Open the file on client B.
3019//         let buffer_b = cx_b
3020//             .background()
3021//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "one.rs"), cx)))
3022//             .await
3023//             .unwrap();
3024
3025//         // Request references to a symbol as the guest.
3026//         let fake_language_server = fake_language_servers.next().await.unwrap();
3027//         fake_language_server.handle_request::<lsp::request::References, _, _>(
3028//             |params, _| async move {
3029//                 assert_eq!(
3030//                     params.text_document_position.text_document.uri.as_str(),
3031//                     "file:///root-1/one.rs"
3032//                 );
3033//                 Ok(Some(vec![
3034//                     lsp::Location {
3035//                         uri: lsp::Url::from_file_path("/root-1/two.rs").unwrap(),
3036//                         range: lsp::Range::new(
3037//                             lsp::Position::new(0, 24),
3038//                             lsp::Position::new(0, 27),
3039//                         ),
3040//                     },
3041//                     lsp::Location {
3042//                         uri: lsp::Url::from_file_path("/root-1/two.rs").unwrap(),
3043//                         range: lsp::Range::new(
3044//                             lsp::Position::new(0, 35),
3045//                             lsp::Position::new(0, 38),
3046//                         ),
3047//                     },
3048//                     lsp::Location {
3049//                         uri: lsp::Url::from_file_path("/root-2/three.rs").unwrap(),
3050//                         range: lsp::Range::new(
3051//                             lsp::Position::new(0, 37),
3052//                             lsp::Position::new(0, 40),
3053//                         ),
3054//                     },
3055//                 ]))
3056//             },
3057//         );
3058
3059//         let references = project_b
3060//             .update(cx_b, |p, cx| p.references(&buffer_b, 7, cx))
3061//             .await
3062//             .unwrap();
3063//         cx_b.read(|cx| {
3064//             assert_eq!(references.len(), 3);
3065//             assert_eq!(project_b.read(cx).worktrees(cx).count(), 2);
3066
3067//             let two_buffer = references[0].buffer.read(cx);
3068//             let three_buffer = references[2].buffer.read(cx);
3069//             assert_eq!(
3070//                 two_buffer.file().unwrap().path().as_ref(),
3071//                 Path::new("two.rs")
3072//             );
3073//             assert_eq!(references[1].buffer, references[0].buffer);
3074//             assert_eq!(
3075//                 three_buffer.file().unwrap().full_path(cx),
3076//                 Path::new("three.rs")
3077//             );
3078
3079//             assert_eq!(references[0].range.to_offset(&two_buffer), 24..27);
3080//             assert_eq!(references[1].range.to_offset(&two_buffer), 35..38);
3081//             assert_eq!(references[2].range.to_offset(&three_buffer), 37..40);
3082//         });
3083//     }
3084
3085//     #[gpui::test(iterations = 10)]
3086//     async fn test_project_search(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
3087//         cx_a.foreground().forbid_parking();
3088//         let lang_registry = Arc::new(LanguageRegistry::test());
3089//         let fs = FakeFs::new(cx_a.background());
3090//         fs.insert_tree(
3091//             "/root-1",
3092//             json!({
3093//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
3094//                 "a": "hello world",
3095//                 "b": "goodnight moon",
3096//                 "c": "a world of goo",
3097//                 "d": "world champion of clown world",
3098//             }),
3099//         )
3100//         .await;
3101//         fs.insert_tree(
3102//             "/root-2",
3103//             json!({
3104//                 "e": "disney world is fun",
3105//             }),
3106//         )
3107//         .await;
3108
3109//         // Connect to a server as 2 clients.
3110//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
3111//         let client_a = server.create_client(cx_a, "user_a").await;
3112//         let client_b = server.create_client(cx_b, "user_b").await;
3113
3114//         // Share a project as client A
3115//         let project_a = cx_a.update(|cx| {
3116//             Project::local(
3117//                 client_a.clone(),
3118//                 client_a.user_store.clone(),
3119//                 lang_registry.clone(),
3120//                 fs.clone(),
3121//                 cx,
3122//             )
3123//         });
3124//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3125
3126//         let (worktree_1, _) = project_a
3127//             .update(cx_a, |p, cx| {
3128//                 p.find_or_create_local_worktree("/root-1", true, cx)
3129//             })
3130//             .await
3131//             .unwrap();
3132//         worktree_1
3133//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3134//             .await;
3135//         let (worktree_2, _) = project_a
3136//             .update(cx_a, |p, cx| {
3137//                 p.find_or_create_local_worktree("/root-2", true, cx)
3138//             })
3139//             .await
3140//             .unwrap();
3141//         worktree_2
3142//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3143//             .await;
3144
3145//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3146
3147//         // Join the worktree as client B.
3148//         let project_b = Project::remote(
3149//             project_id,
3150//             client_b.clone(),
3151//             client_b.user_store.clone(),
3152//             lang_registry.clone(),
3153//             fs.clone(),
3154//             &mut cx_b.to_async(),
3155//         )
3156//         .await
3157//         .unwrap();
3158
3159//         let results = project_b
3160//             .update(cx_b, |project, cx| {
3161//                 project.search(SearchQuery::text("world", false, false), cx)
3162//             })
3163//             .await
3164//             .unwrap();
3165
3166//         let mut ranges_by_path = results
3167//             .into_iter()
3168//             .map(|(buffer, ranges)| {
3169//                 buffer.read_with(cx_b, |buffer, cx| {
3170//                     let path = buffer.file().unwrap().full_path(cx);
3171//                     let offset_ranges = ranges
3172//                         .into_iter()
3173//                         .map(|range| range.to_offset(buffer))
3174//                         .collect::<Vec<_>>();
3175//                     (path, offset_ranges)
3176//                 })
3177//             })
3178//             .collect::<Vec<_>>();
3179//         ranges_by_path.sort_by_key(|(path, _)| path.clone());
3180
3181//         assert_eq!(
3182//             ranges_by_path,
3183//             &[
3184//                 (PathBuf::from("root-1/a"), vec![6..11]),
3185//                 (PathBuf::from("root-1/c"), vec![2..7]),
3186//                 (PathBuf::from("root-1/d"), vec![0..5, 24..29]),
3187//                 (PathBuf::from("root-2/e"), vec![7..12]),
3188//             ]
3189//         );
3190//     }
3191
3192//     #[gpui::test(iterations = 10)]
3193//     async fn test_document_highlights(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
3194//         cx_a.foreground().forbid_parking();
3195//         let lang_registry = Arc::new(LanguageRegistry::test());
3196//         let fs = FakeFs::new(cx_a.background());
3197//         fs.insert_tree(
3198//             "/root-1",
3199//             json!({
3200//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
3201//                 "main.rs": "fn double(number: i32) -> i32 { number + number }",
3202//             }),
3203//         )
3204//         .await;
3205
3206//         // Set up a fake language server.
3207//         let mut language = Language::new(
3208//             LanguageConfig {
3209//                 name: "Rust".into(),
3210//                 path_suffixes: vec!["rs".to_string()],
3211//                 ..Default::default()
3212//             },
3213//             Some(tree_sitter_rust::language()),
3214//         );
3215//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
3216//         lang_registry.add(Arc::new(language));
3217
3218//         // Connect to a server as 2 clients.
3219//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
3220//         let client_a = server.create_client(cx_a, "user_a").await;
3221//         let client_b = server.create_client(cx_b, "user_b").await;
3222
3223//         // Share a project as client A
3224//         let project_a = cx_a.update(|cx| {
3225//             Project::local(
3226//                 client_a.clone(),
3227//                 client_a.user_store.clone(),
3228//                 lang_registry.clone(),
3229//                 fs.clone(),
3230//                 cx,
3231//             )
3232//         });
3233//         let (worktree_a, _) = project_a
3234//             .update(cx_a, |p, cx| {
3235//                 p.find_or_create_local_worktree("/root-1", true, cx)
3236//             })
3237//             .await
3238//             .unwrap();
3239//         worktree_a
3240//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3241//             .await;
3242//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3243//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
3244//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3245
3246//         // Join the worktree as client B.
3247//         let project_b = Project::remote(
3248//             project_id,
3249//             client_b.clone(),
3250//             client_b.user_store.clone(),
3251//             lang_registry.clone(),
3252//             fs.clone(),
3253//             &mut cx_b.to_async(),
3254//         )
3255//         .await
3256//         .unwrap();
3257
3258//         // Open the file on client B.
3259//         let buffer_b = cx_b
3260//             .background()
3261//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)))
3262//             .await
3263//             .unwrap();
3264
3265//         // Request document highlights as the guest.
3266//         let fake_language_server = fake_language_servers.next().await.unwrap();
3267//         fake_language_server.handle_request::<lsp::request::DocumentHighlightRequest, _, _>(
3268//             |params, _| async move {
3269//                 assert_eq!(
3270//                     params
3271//                         .text_document_position_params
3272//                         .text_document
3273//                         .uri
3274//                         .as_str(),
3275//                     "file:///root-1/main.rs"
3276//                 );
3277//                 assert_eq!(
3278//                     params.text_document_position_params.position,
3279//                     lsp::Position::new(0, 34)
3280//                 );
3281//                 Ok(Some(vec![
3282//                     lsp::DocumentHighlight {
3283//                         kind: Some(lsp::DocumentHighlightKind::WRITE),
3284//                         range: lsp::Range::new(
3285//                             lsp::Position::new(0, 10),
3286//                             lsp::Position::new(0, 16),
3287//                         ),
3288//                     },
3289//                     lsp::DocumentHighlight {
3290//                         kind: Some(lsp::DocumentHighlightKind::READ),
3291//                         range: lsp::Range::new(
3292//                             lsp::Position::new(0, 32),
3293//                             lsp::Position::new(0, 38),
3294//                         ),
3295//                     },
3296//                     lsp::DocumentHighlight {
3297//                         kind: Some(lsp::DocumentHighlightKind::READ),
3298//                         range: lsp::Range::new(
3299//                             lsp::Position::new(0, 41),
3300//                             lsp::Position::new(0, 47),
3301//                         ),
3302//                     },
3303//                 ]))
3304//             },
3305//         );
3306
3307//         let highlights = project_b
3308//             .update(cx_b, |p, cx| p.document_highlights(&buffer_b, 34, cx))
3309//             .await
3310//             .unwrap();
3311//         buffer_b.read_with(cx_b, |buffer, _| {
3312//             let snapshot = buffer.snapshot();
3313
3314//             let highlights = highlights
3315//                 .into_iter()
3316//                 .map(|highlight| (highlight.kind, highlight.range.to_offset(&snapshot)))
3317//                 .collect::<Vec<_>>();
3318//             assert_eq!(
3319//                 highlights,
3320//                 &[
3321//                     (lsp::DocumentHighlightKind::WRITE, 10..16),
3322//                     (lsp::DocumentHighlightKind::READ, 32..38),
3323//                     (lsp::DocumentHighlightKind::READ, 41..47)
3324//                 ]
3325//             )
3326//         });
3327//     }
3328
3329//     #[gpui::test(iterations = 10)]
3330//     async fn test_project_symbols(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
3331//         cx_a.foreground().forbid_parking();
3332//         let lang_registry = Arc::new(LanguageRegistry::test());
3333//         let fs = FakeFs::new(cx_a.background());
3334//         fs.insert_tree(
3335//             "/code",
3336//             json!({
3337//                 "crate-1": {
3338//                     ".zed.toml": r#"collaborators = ["user_b"]"#,
3339//                     "one.rs": "const ONE: usize = 1;",
3340//                 },
3341//                 "crate-2": {
3342//                     "two.rs": "const TWO: usize = 2; const THREE: usize = 3;",
3343//                 },
3344//                 "private": {
3345//                     "passwords.txt": "the-password",
3346//                 }
3347//             }),
3348//         )
3349//         .await;
3350
3351//         // Set up a fake language server.
3352//         let mut language = Language::new(
3353//             LanguageConfig {
3354//                 name: "Rust".into(),
3355//                 path_suffixes: vec!["rs".to_string()],
3356//                 ..Default::default()
3357//             },
3358//             Some(tree_sitter_rust::language()),
3359//         );
3360//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
3361//         lang_registry.add(Arc::new(language));
3362
3363//         // Connect to a server as 2 clients.
3364//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
3365//         let client_a = server.create_client(cx_a, "user_a").await;
3366//         let client_b = server.create_client(cx_b, "user_b").await;
3367
3368//         // Share a project as client A
3369//         let project_a = cx_a.update(|cx| {
3370//             Project::local(
3371//                 client_a.clone(),
3372//                 client_a.user_store.clone(),
3373//                 lang_registry.clone(),
3374//                 fs.clone(),
3375//                 cx,
3376//             )
3377//         });
3378//         let (worktree_a, _) = project_a
3379//             .update(cx_a, |p, cx| {
3380//                 p.find_or_create_local_worktree("/code/crate-1", true, cx)
3381//             })
3382//             .await
3383//             .unwrap();
3384//         worktree_a
3385//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3386//             .await;
3387//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3388//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
3389//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3390
3391//         // Join the worktree as client B.
3392//         let project_b = Project::remote(
3393//             project_id,
3394//             client_b.clone(),
3395//             client_b.user_store.clone(),
3396//             lang_registry.clone(),
3397//             fs.clone(),
3398//             &mut cx_b.to_async(),
3399//         )
3400//         .await
3401//         .unwrap();
3402
3403//         // Cause the language server to start.
3404//         let _buffer = cx_b
3405//             .background()
3406//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "one.rs"), cx)))
3407//             .await
3408//             .unwrap();
3409
3410//         let fake_language_server = fake_language_servers.next().await.unwrap();
3411//         fake_language_server.handle_request::<lsp::request::WorkspaceSymbol, _, _>(
3412//             |_, _| async move {
3413//                 #[allow(deprecated)]
3414//                 Ok(Some(vec![lsp::SymbolInformation {
3415//                     name: "TWO".into(),
3416//                     location: lsp::Location {
3417//                         uri: lsp::Url::from_file_path("/code/crate-2/two.rs").unwrap(),
3418//                         range: lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)),
3419//                     },
3420//                     kind: lsp::SymbolKind::CONSTANT,
3421//                     tags: None,
3422//                     container_name: None,
3423//                     deprecated: None,
3424//                 }]))
3425//             },
3426//         );
3427
3428//         // Request the definition of a symbol as the guest.
3429//         let symbols = project_b
3430//             .update(cx_b, |p, cx| p.symbols("two", cx))
3431//             .await
3432//             .unwrap();
3433//         assert_eq!(symbols.len(), 1);
3434//         assert_eq!(symbols[0].name, "TWO");
3435
3436//         // Open one of the returned symbols.
3437//         let buffer_b_2 = project_b
3438//             .update(cx_b, |project, cx| {
3439//                 project.open_buffer_for_symbol(&symbols[0], cx)
3440//             })
3441//             .await
3442//             .unwrap();
3443//         buffer_b_2.read_with(cx_b, |buffer, _| {
3444//             assert_eq!(
3445//                 buffer.file().unwrap().path().as_ref(),
3446//                 Path::new("../crate-2/two.rs")
3447//             );
3448//         });
3449
3450//         // Attempt to craft a symbol and violate host's privacy by opening an arbitrary file.
3451//         let mut fake_symbol = symbols[0].clone();
3452//         fake_symbol.path = Path::new("/code/secrets").into();
3453//         let error = project_b
3454//             .update(cx_b, |project, cx| {
3455//                 project.open_buffer_for_symbol(&fake_symbol, cx)
3456//             })
3457//             .await
3458//             .unwrap_err();
3459//         assert!(error.to_string().contains("invalid symbol signature"));
3460//     }
3461
3462//     #[gpui::test(iterations = 10)]
3463//     async fn test_open_buffer_while_getting_definition_pointing_to_it(
3464//         cx_a: &mut TestAppContext,
3465//         cx_b: &mut TestAppContext,
3466//         mut rng: StdRng,
3467//     ) {
3468//         cx_a.foreground().forbid_parking();
3469//         let lang_registry = Arc::new(LanguageRegistry::test());
3470//         let fs = FakeFs::new(cx_a.background());
3471//         fs.insert_tree(
3472//             "/root",
3473//             json!({
3474//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
3475//                 "a.rs": "const ONE: usize = b::TWO;",
3476//                 "b.rs": "const TWO: usize = 2",
3477//             }),
3478//         )
3479//         .await;
3480
3481//         // Set up a fake language server.
3482//         let mut language = Language::new(
3483//             LanguageConfig {
3484//                 name: "Rust".into(),
3485//                 path_suffixes: vec!["rs".to_string()],
3486//                 ..Default::default()
3487//             },
3488//             Some(tree_sitter_rust::language()),
3489//         );
3490//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
3491//         lang_registry.add(Arc::new(language));
3492
3493//         // Connect to a server as 2 clients.
3494//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
3495//         let client_a = server.create_client(cx_a, "user_a").await;
3496//         let client_b = server.create_client(cx_b, "user_b").await;
3497
3498//         // Share a project as client A
3499//         let project_a = cx_a.update(|cx| {
3500//             Project::local(
3501//                 client_a.clone(),
3502//                 client_a.user_store.clone(),
3503//                 lang_registry.clone(),
3504//                 fs.clone(),
3505//                 cx,
3506//             )
3507//         });
3508
3509//         let (worktree_a, _) = project_a
3510//             .update(cx_a, |p, cx| {
3511//                 p.find_or_create_local_worktree("/root", true, cx)
3512//             })
3513//             .await
3514//             .unwrap();
3515//         worktree_a
3516//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3517//             .await;
3518//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3519//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
3520//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3521
3522//         // Join the worktree as client B.
3523//         let project_b = Project::remote(
3524//             project_id,
3525//             client_b.clone(),
3526//             client_b.user_store.clone(),
3527//             lang_registry.clone(),
3528//             fs.clone(),
3529//             &mut cx_b.to_async(),
3530//         )
3531//         .await
3532//         .unwrap();
3533
3534//         let buffer_b1 = cx_b
3535//             .background()
3536//             .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)))
3537//             .await
3538//             .unwrap();
3539
3540//         let fake_language_server = fake_language_servers.next().await.unwrap();
3541//         fake_language_server.handle_request::<lsp::request::GotoDefinition, _, _>(
3542//             |_, _| async move {
3543//                 Ok(Some(lsp::GotoDefinitionResponse::Scalar(
3544//                     lsp::Location::new(
3545//                         lsp::Url::from_file_path("/root/b.rs").unwrap(),
3546//                         lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)),
3547//                     ),
3548//                 )))
3549//             },
3550//         );
3551
3552//         let definitions;
3553//         let buffer_b2;
3554//         if rng.gen() {
3555//             definitions = project_b.update(cx_b, |p, cx| p.definition(&buffer_b1, 23, cx));
3556//             buffer_b2 = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "b.rs"), cx));
3557//         } else {
3558//             buffer_b2 = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "b.rs"), cx));
3559//             definitions = project_b.update(cx_b, |p, cx| p.definition(&buffer_b1, 23, cx));
3560//         }
3561
3562//         let buffer_b2 = buffer_b2.await.unwrap();
3563//         let definitions = definitions.await.unwrap();
3564//         assert_eq!(definitions.len(), 1);
3565//         assert_eq!(definitions[0].buffer, buffer_b2);
3566//     }
3567
3568//     #[gpui::test(iterations = 10)]
3569//     async fn test_collaborating_with_code_actions(
3570//         cx_a: &mut TestAppContext,
3571//         cx_b: &mut TestAppContext,
3572//     ) {
3573//         cx_a.foreground().forbid_parking();
3574//         let lang_registry = Arc::new(LanguageRegistry::test());
3575//         let fs = FakeFs::new(cx_a.background());
3576//         cx_b.update(|cx| editor::init(cx));
3577
3578//         // Set up a fake language server.
3579//         let mut language = Language::new(
3580//             LanguageConfig {
3581//                 name: "Rust".into(),
3582//                 path_suffixes: vec!["rs".to_string()],
3583//                 ..Default::default()
3584//             },
3585//             Some(tree_sitter_rust::language()),
3586//         );
3587//         let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
3588//         lang_registry.add(Arc::new(language));
3589
3590//         // Connect to a server as 2 clients.
3591//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
3592//         let client_a = server.create_client(cx_a, "user_a").await;
3593//         let client_b = server.create_client(cx_b, "user_b").await;
3594
3595//         // Share a project as client A
3596//         fs.insert_tree(
3597//             "/a",
3598//             json!({
3599//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
3600//                 "main.rs": "mod other;\nfn main() { let foo = other::foo(); }",
3601//                 "other.rs": "pub fn foo() -> usize { 4 }",
3602//             }),
3603//         )
3604//         .await;
3605//         let project_a = cx_a.update(|cx| {
3606//             Project::local(
3607//                 client_a.clone(),
3608//                 client_a.user_store.clone(),
3609//                 lang_registry.clone(),
3610//                 fs.clone(),
3611//                 cx,
3612//             )
3613//         });
3614//         let (worktree_a, _) = project_a
3615//             .update(cx_a, |p, cx| {
3616//                 p.find_or_create_local_worktree("/a", true, cx)
3617//             })
3618//             .await
3619//             .unwrap();
3620//         worktree_a
3621//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3622//             .await;
3623//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3624//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
3625//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3626
3627//         // Join the worktree as client B.
3628//         let project_b = Project::remote(
3629//             project_id,
3630//             client_b.clone(),
3631//             client_b.user_store.clone(),
3632//             lang_registry.clone(),
3633//             fs.clone(),
3634//             &mut cx_b.to_async(),
3635//         )
3636//         .await
3637//         .unwrap();
3638//         let mut params = cx_b.update(WorkspaceParams::test);
3639//         params.languages = lang_registry.clone();
3640//         params.client = client_b.client.clone();
3641//         params.user_store = client_b.user_store.clone();
3642//         params.project = project_b;
3643
3644//         let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::new(&params, cx));
3645//         let editor_b = workspace_b
3646//             .update(cx_b, |workspace, cx| {
3647//                 workspace.open_path((worktree_id, "main.rs"), cx)
3648//             })
3649//             .await
3650//             .unwrap()
3651//             .downcast::<Editor>()
3652//             .unwrap();
3653
3654//         let mut fake_language_server = fake_language_servers.next().await.unwrap();
3655//         fake_language_server
3656//             .handle_request::<lsp::request::CodeActionRequest, _, _>(|params, _| async move {
3657//                 assert_eq!(
3658//                     params.text_document.uri,
3659//                     lsp::Url::from_file_path("/a/main.rs").unwrap(),
3660//                 );
3661//                 assert_eq!(params.range.start, lsp::Position::new(0, 0));
3662//                 assert_eq!(params.range.end, lsp::Position::new(0, 0));
3663//                 Ok(None)
3664//             })
3665//             .next()
3666//             .await;
3667
3668//         // Move cursor to a location that contains code actions.
3669//         editor_b.update(cx_b, |editor, cx| {
3670//             editor.select_ranges([Point::new(1, 31)..Point::new(1, 31)], None, cx);
3671//             cx.focus(&editor_b);
3672//         });
3673
3674//         fake_language_server
3675//             .handle_request::<lsp::request::CodeActionRequest, _, _>(|params, _| async move {
3676//                 assert_eq!(
3677//                     params.text_document.uri,
3678//                     lsp::Url::from_file_path("/a/main.rs").unwrap(),
3679//                 );
3680//                 assert_eq!(params.range.start, lsp::Position::new(1, 31));
3681//                 assert_eq!(params.range.end, lsp::Position::new(1, 31));
3682
3683//                 Ok(Some(vec![lsp::CodeActionOrCommand::CodeAction(
3684//                     lsp::CodeAction {
3685//                         title: "Inline into all callers".to_string(),
3686//                         edit: Some(lsp::WorkspaceEdit {
3687//                             changes: Some(
3688//                                 [
3689//                                     (
3690//                                         lsp::Url::from_file_path("/a/main.rs").unwrap(),
3691//                                         vec![lsp::TextEdit::new(
3692//                                             lsp::Range::new(
3693//                                                 lsp::Position::new(1, 22),
3694//                                                 lsp::Position::new(1, 34),
3695//                                             ),
3696//                                             "4".to_string(),
3697//                                         )],
3698//                                     ),
3699//                                     (
3700//                                         lsp::Url::from_file_path("/a/other.rs").unwrap(),
3701//                                         vec![lsp::TextEdit::new(
3702//                                             lsp::Range::new(
3703//                                                 lsp::Position::new(0, 0),
3704//                                                 lsp::Position::new(0, 27),
3705//                                             ),
3706//                                             "".to_string(),
3707//                                         )],
3708//                                     ),
3709//                                 ]
3710//                                 .into_iter()
3711//                                 .collect(),
3712//                             ),
3713//                             ..Default::default()
3714//                         }),
3715//                         data: Some(json!({
3716//                             "codeActionParams": {
3717//                                 "range": {
3718//                                     "start": {"line": 1, "column": 31},
3719//                                     "end": {"line": 1, "column": 31},
3720//                                 }
3721//                             }
3722//                         })),
3723//                         ..Default::default()
3724//                     },
3725//                 )]))
3726//             })
3727//             .next()
3728//             .await;
3729
3730//         // Toggle code actions and wait for them to display.
3731//         editor_b.update(cx_b, |editor, cx| {
3732//             editor.toggle_code_actions(
3733//                 &ToggleCodeActions {
3734//                     deployed_from_indicator: false,
3735//                 },
3736//                 cx,
3737//             );
3738//         });
3739//         editor_b
3740//             .condition(&cx_b, |editor, _| editor.context_menu_visible())
3741//             .await;
3742
3743//         fake_language_server.remove_request_handler::<lsp::request::CodeActionRequest>();
3744
3745//         // Confirming the code action will trigger a resolve request.
3746//         let confirm_action = workspace_b
3747//             .update(cx_b, |workspace, cx| {
3748//                 Editor::confirm_code_action(workspace, &ConfirmCodeAction { item_ix: Some(0) }, cx)
3749//             })
3750//             .unwrap();
3751//         fake_language_server.handle_request::<lsp::request::CodeActionResolveRequest, _, _>(
3752//             |_, _| async move {
3753//                 Ok(lsp::CodeAction {
3754//                     title: "Inline into all callers".to_string(),
3755//                     edit: Some(lsp::WorkspaceEdit {
3756//                         changes: Some(
3757//                             [
3758//                                 (
3759//                                     lsp::Url::from_file_path("/a/main.rs").unwrap(),
3760//                                     vec![lsp::TextEdit::new(
3761//                                         lsp::Range::new(
3762//                                             lsp::Position::new(1, 22),
3763//                                             lsp::Position::new(1, 34),
3764//                                         ),
3765//                                         "4".to_string(),
3766//                                     )],
3767//                                 ),
3768//                                 (
3769//                                     lsp::Url::from_file_path("/a/other.rs").unwrap(),
3770//                                     vec![lsp::TextEdit::new(
3771//                                         lsp::Range::new(
3772//                                             lsp::Position::new(0, 0),
3773//                                             lsp::Position::new(0, 27),
3774//                                         ),
3775//                                         "".to_string(),
3776//                                     )],
3777//                                 ),
3778//                             ]
3779//                             .into_iter()
3780//                             .collect(),
3781//                         ),
3782//                         ..Default::default()
3783//                     }),
3784//                     ..Default::default()
3785//                 })
3786//             },
3787//         );
3788
3789//         // After the action is confirmed, an editor containing both modified files is opened.
3790//         confirm_action.await.unwrap();
3791//         let code_action_editor = workspace_b.read_with(cx_b, |workspace, cx| {
3792//             workspace
3793//                 .active_item(cx)
3794//                 .unwrap()
3795//                 .downcast::<Editor>()
3796//                 .unwrap()
3797//         });
3798//         code_action_editor.update(cx_b, |editor, cx| {
3799//             assert_eq!(editor.text(cx), "\nmod other;\nfn main() { let foo = 4; }");
3800//             editor.undo(&Undo, cx);
3801//             assert_eq!(
3802//                 editor.text(cx),
3803//                 "pub fn foo() -> usize { 4 }\nmod other;\nfn main() { let foo = other::foo(); }"
3804//             );
3805//             editor.redo(&Redo, cx);
3806//             assert_eq!(editor.text(cx), "\nmod other;\nfn main() { let foo = 4; }");
3807//         });
3808//     }
3809
3810//     #[gpui::test(iterations = 10)]
3811//     async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
3812//         cx_a.foreground().forbid_parking();
3813//         let lang_registry = Arc::new(LanguageRegistry::test());
3814//         let fs = FakeFs::new(cx_a.background());
3815//         cx_b.update(|cx| editor::init(cx));
3816
3817//         // Set up a fake language server.
3818//         let mut language = Language::new(
3819//             LanguageConfig {
3820//                 name: "Rust".into(),
3821//                 path_suffixes: vec!["rs".to_string()],
3822//                 ..Default::default()
3823//             },
3824//             Some(tree_sitter_rust::language()),
3825//         );
3826//         let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
3827//             capabilities: lsp::ServerCapabilities {
3828//                 rename_provider: Some(lsp::OneOf::Right(lsp::RenameOptions {
3829//                     prepare_provider: Some(true),
3830//                     work_done_progress_options: Default::default(),
3831//                 })),
3832//                 ..Default::default()
3833//             },
3834//             ..Default::default()
3835//         });
3836//         lang_registry.add(Arc::new(language));
3837
3838//         // Connect to a server as 2 clients.
3839//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
3840//         let client_a = server.create_client(cx_a, "user_a").await;
3841//         let client_b = server.create_client(cx_b, "user_b").await;
3842
3843//         // Share a project as client A
3844//         fs.insert_tree(
3845//             "/dir",
3846//             json!({
3847//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
3848//                 "one.rs": "const ONE: usize = 1;",
3849//                 "two.rs": "const TWO: usize = one::ONE + one::ONE;"
3850//             }),
3851//         )
3852//         .await;
3853//         let project_a = cx_a.update(|cx| {
3854//             Project::local(
3855//                 client_a.clone(),
3856//                 client_a.user_store.clone(),
3857//                 lang_registry.clone(),
3858//                 fs.clone(),
3859//                 cx,
3860//             )
3861//         });
3862//         let (worktree_a, _) = project_a
3863//             .update(cx_a, |p, cx| {
3864//                 p.find_or_create_local_worktree("/dir", true, cx)
3865//             })
3866//             .await
3867//             .unwrap();
3868//         worktree_a
3869//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
3870//             .await;
3871//         let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await;
3872//         let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id());
3873//         project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap();
3874
3875//         // Join the worktree as client B.
3876//         let project_b = Project::remote(
3877//             project_id,
3878//             client_b.clone(),
3879//             client_b.user_store.clone(),
3880//             lang_registry.clone(),
3881//             fs.clone(),
3882//             &mut cx_b.to_async(),
3883//         )
3884//         .await
3885//         .unwrap();
3886//         let mut params = cx_b.update(WorkspaceParams::test);
3887//         params.languages = lang_registry.clone();
3888//         params.client = client_b.client.clone();
3889//         params.user_store = client_b.user_store.clone();
3890//         params.project = project_b;
3891
3892//         let (_window_b, workspace_b) = cx_b.add_window(|cx| Workspace::new(&params, cx));
3893//         let editor_b = workspace_b
3894//             .update(cx_b, |workspace, cx| {
3895//                 workspace.open_path((worktree_id, "one.rs"), cx)
3896//             })
3897//             .await
3898//             .unwrap()
3899//             .downcast::<Editor>()
3900//             .unwrap();
3901//         let fake_language_server = fake_language_servers.next().await.unwrap();
3902
3903//         // Move cursor to a location that can be renamed.
3904//         let prepare_rename = editor_b.update(cx_b, |editor, cx| {
3905//             editor.select_ranges([7..7], None, cx);
3906//             editor.rename(&Rename, cx).unwrap()
3907//         });
3908
3909//         fake_language_server
3910//             .handle_request::<lsp::request::PrepareRenameRequest, _, _>(|params, _| async move {
3911//                 assert_eq!(params.text_document.uri.as_str(), "file:///dir/one.rs");
3912//                 assert_eq!(params.position, lsp::Position::new(0, 7));
3913//                 Ok(Some(lsp::PrepareRenameResponse::Range(lsp::Range::new(
3914//                     lsp::Position::new(0, 6),
3915//                     lsp::Position::new(0, 9),
3916//                 ))))
3917//             })
3918//             .next()
3919//             .await
3920//             .unwrap();
3921//         prepare_rename.await.unwrap();
3922//         editor_b.update(cx_b, |editor, cx| {
3923//             let rename = editor.pending_rename().unwrap();
3924//             let buffer = editor.buffer().read(cx).snapshot(cx);
3925//             assert_eq!(
3926//                 rename.range.start.to_offset(&buffer)..rename.range.end.to_offset(&buffer),
3927//                 6..9
3928//             );
3929//             rename.editor.update(cx, |rename_editor, cx| {
3930//                 rename_editor.buffer().update(cx, |rename_buffer, cx| {
3931//                     rename_buffer.edit([0..3], "THREE", cx);
3932//                 });
3933//             });
3934//         });
3935
3936//         let confirm_rename = workspace_b.update(cx_b, |workspace, cx| {
3937//             Editor::confirm_rename(workspace, &ConfirmRename, cx).unwrap()
3938//         });
3939//         fake_language_server
3940//             .handle_request::<lsp::request::Rename, _, _>(|params, _| async move {
3941//                 assert_eq!(
3942//                     params.text_document_position.text_document.uri.as_str(),
3943//                     "file:///dir/one.rs"
3944//                 );
3945//                 assert_eq!(
3946//                     params.text_document_position.position,
3947//                     lsp::Position::new(0, 6)
3948//                 );
3949//                 assert_eq!(params.new_name, "THREE");
3950//                 Ok(Some(lsp::WorkspaceEdit {
3951//                     changes: Some(
3952//                         [
3953//                             (
3954//                                 lsp::Url::from_file_path("/dir/one.rs").unwrap(),
3955//                                 vec![lsp::TextEdit::new(
3956//                                     lsp::Range::new(
3957//                                         lsp::Position::new(0, 6),
3958//                                         lsp::Position::new(0, 9),
3959//                                     ),
3960//                                     "THREE".to_string(),
3961//                                 )],
3962//                             ),
3963//                             (
3964//                                 lsp::Url::from_file_path("/dir/two.rs").unwrap(),
3965//                                 vec![
3966//                                     lsp::TextEdit::new(
3967//                                         lsp::Range::new(
3968//                                             lsp::Position::new(0, 24),
3969//                                             lsp::Position::new(0, 27),
3970//                                         ),
3971//                                         "THREE".to_string(),
3972//                                     ),
3973//                                     lsp::TextEdit::new(
3974//                                         lsp::Range::new(
3975//                                             lsp::Position::new(0, 35),
3976//                                             lsp::Position::new(0, 38),
3977//                                         ),
3978//                                         "THREE".to_string(),
3979//                                     ),
3980//                                 ],
3981//                             ),
3982//                         ]
3983//                         .into_iter()
3984//                         .collect(),
3985//                     ),
3986//                     ..Default::default()
3987//                 }))
3988//             })
3989//             .next()
3990//             .await
3991//             .unwrap();
3992//         confirm_rename.await.unwrap();
3993
3994//         let rename_editor = workspace_b.read_with(cx_b, |workspace, cx| {
3995//             workspace
3996//                 .active_item(cx)
3997//                 .unwrap()
3998//                 .downcast::<Editor>()
3999//                 .unwrap()
4000//         });
4001//         rename_editor.update(cx_b, |editor, cx| {
4002//             assert_eq!(
4003//                 editor.text(cx),
4004//                 "const TWO: usize = one::THREE + one::THREE;\nconst THREE: usize = 1;"
4005//             );
4006//             editor.undo(&Undo, cx);
4007//             assert_eq!(
4008//                 editor.text(cx),
4009//                 "const TWO: usize = one::ONE + one::ONE;\nconst ONE: usize = 1;"
4010//             );
4011//             editor.redo(&Redo, cx);
4012//             assert_eq!(
4013//                 editor.text(cx),
4014//                 "const TWO: usize = one::THREE + one::THREE;\nconst THREE: usize = 1;"
4015//             );
4016//         });
4017
4018//         // Ensure temporary rename edits cannot be undone/redone.
4019//         editor_b.update(cx_b, |editor, cx| {
4020//             editor.undo(&Undo, cx);
4021//             assert_eq!(editor.text(cx), "const ONE: usize = 1;");
4022//             editor.undo(&Undo, cx);
4023//             assert_eq!(editor.text(cx), "const ONE: usize = 1;");
4024//             editor.redo(&Redo, cx);
4025//             assert_eq!(editor.text(cx), "const THREE: usize = 1;");
4026//         })
4027//     }
4028
4029//     #[gpui::test(iterations = 10)]
4030//     async fn test_basic_chat(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
4031//         cx_a.foreground().forbid_parking();
4032
4033//         // Connect to a server as 2 clients.
4034//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4035//         let client_a = server.create_client(cx_a, "user_a").await;
4036//         let client_b = server.create_client(cx_b, "user_b").await;
4037
4038//         // Create an org that includes these 2 users.
4039//         let db = &server.app_state.db;
4040//         let org_id = db.create_org("Test Org", "test-org").await.unwrap();
4041//         db.add_org_member(org_id, client_a.current_user_id(&cx_a), false)
4042//             .await
4043//             .unwrap();
4044//         db.add_org_member(org_id, client_b.current_user_id(&cx_b), false)
4045//             .await
4046//             .unwrap();
4047
4048//         // Create a channel that includes all the users.
4049//         let channel_id = db.create_org_channel(org_id, "test-channel").await.unwrap();
4050//         db.add_channel_member(channel_id, client_a.current_user_id(&cx_a), false)
4051//             .await
4052//             .unwrap();
4053//         db.add_channel_member(channel_id, client_b.current_user_id(&cx_b), false)
4054//             .await
4055//             .unwrap();
4056//         db.create_channel_message(
4057//             channel_id,
4058//             client_b.current_user_id(&cx_b),
4059//             "hello A, it's B.",
4060//             OffsetDateTime::now_utc(),
4061//             1,
4062//         )
4063//         .await
4064//         .unwrap();
4065
4066//         let channels_a = cx_a
4067//             .add_model(|cx| ChannelList::new(client_a.user_store.clone(), client_a.clone(), cx));
4068//         channels_a
4069//             .condition(cx_a, |list, _| list.available_channels().is_some())
4070//             .await;
4071//         channels_a.read_with(cx_a, |list, _| {
4072//             assert_eq!(
4073//                 list.available_channels().unwrap(),
4074//                 &[ChannelDetails {
4075//                     id: channel_id.to_proto(),
4076//                     name: "test-channel".to_string()
4077//                 }]
4078//             )
4079//         });
4080//         let channel_a = channels_a.update(cx_a, |this, cx| {
4081//             this.get_channel(channel_id.to_proto(), cx).unwrap()
4082//         });
4083//         channel_a.read_with(cx_a, |channel, _| assert!(channel.messages().is_empty()));
4084//         channel_a
4085//             .condition(&cx_a, |channel, _| {
4086//                 channel_messages(channel)
4087//                     == [("user_b".to_string(), "hello A, it's B.".to_string(), false)]
4088//             })
4089//             .await;
4090
4091//         let channels_b = cx_b
4092//             .add_model(|cx| ChannelList::new(client_b.user_store.clone(), client_b.clone(), cx));
4093//         channels_b
4094//             .condition(cx_b, |list, _| list.available_channels().is_some())
4095//             .await;
4096//         channels_b.read_with(cx_b, |list, _| {
4097//             assert_eq!(
4098//                 list.available_channels().unwrap(),
4099//                 &[ChannelDetails {
4100//                     id: channel_id.to_proto(),
4101//                     name: "test-channel".to_string()
4102//                 }]
4103//             )
4104//         });
4105
4106//         let channel_b = channels_b.update(cx_b, |this, cx| {
4107//             this.get_channel(channel_id.to_proto(), cx).unwrap()
4108//         });
4109//         channel_b.read_with(cx_b, |channel, _| assert!(channel.messages().is_empty()));
4110//         channel_b
4111//             .condition(&cx_b, |channel, _| {
4112//                 channel_messages(channel)
4113//                     == [("user_b".to_string(), "hello A, it's B.".to_string(), false)]
4114//             })
4115//             .await;
4116
4117//         channel_a
4118//             .update(cx_a, |channel, cx| {
4119//                 channel
4120//                     .send_message("oh, hi B.".to_string(), cx)
4121//                     .unwrap()
4122//                     .detach();
4123//                 let task = channel.send_message("sup".to_string(), cx).unwrap();
4124//                 assert_eq!(
4125//                     channel_messages(channel),
4126//                     &[
4127//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4128//                         ("user_a".to_string(), "oh, hi B.".to_string(), true),
4129//                         ("user_a".to_string(), "sup".to_string(), true)
4130//                     ]
4131//                 );
4132//                 task
4133//             })
4134//             .await
4135//             .unwrap();
4136
4137//         channel_b
4138//             .condition(&cx_b, |channel, _| {
4139//                 channel_messages(channel)
4140//                     == [
4141//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4142//                         ("user_a".to_string(), "oh, hi B.".to_string(), false),
4143//                         ("user_a".to_string(), "sup".to_string(), false),
4144//                     ]
4145//             })
4146//             .await;
4147
4148//         assert_eq!(
4149//             server
4150//                 .state()
4151//                 .await
4152//                 .channel(channel_id)
4153//                 .unwrap()
4154//                 .connection_ids
4155//                 .len(),
4156//             2
4157//         );
4158//         cx_b.update(|_| drop(channel_b));
4159//         server
4160//             .condition(|state| state.channel(channel_id).unwrap().connection_ids.len() == 1)
4161//             .await;
4162
4163//         cx_a.update(|_| drop(channel_a));
4164//         server
4165//             .condition(|state| state.channel(channel_id).is_none())
4166//             .await;
4167//     }
4168
4169//     #[gpui::test(iterations = 10)]
4170//     async fn test_chat_message_validation(cx_a: &mut TestAppContext) {
4171//         cx_a.foreground().forbid_parking();
4172
4173//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4174//         let client_a = server.create_client(cx_a, "user_a").await;
4175
4176//         let db = &server.app_state.db;
4177//         let org_id = db.create_org("Test Org", "test-org").await.unwrap();
4178//         let channel_id = db.create_org_channel(org_id, "test-channel").await.unwrap();
4179//         db.add_org_member(org_id, client_a.current_user_id(&cx_a), false)
4180//             .await
4181//             .unwrap();
4182//         db.add_channel_member(channel_id, client_a.current_user_id(&cx_a), false)
4183//             .await
4184//             .unwrap();
4185
4186//         let channels_a = cx_a
4187//             .add_model(|cx| ChannelList::new(client_a.user_store.clone(), client_a.clone(), cx));
4188//         channels_a
4189//             .condition(cx_a, |list, _| list.available_channels().is_some())
4190//             .await;
4191//         let channel_a = channels_a.update(cx_a, |this, cx| {
4192//             this.get_channel(channel_id.to_proto(), cx).unwrap()
4193//         });
4194
4195//         // Messages aren't allowed to be too long.
4196//         channel_a
4197//             .update(cx_a, |channel, cx| {
4198//                 let long_body = "this is long.\n".repeat(1024);
4199//                 channel.send_message(long_body, cx).unwrap()
4200//             })
4201//             .await
4202//             .unwrap_err();
4203
4204//         // Messages aren't allowed to be blank.
4205//         channel_a.update(cx_a, |channel, cx| {
4206//             channel.send_message(String::new(), cx).unwrap_err()
4207//         });
4208
4209//         // Leading and trailing whitespace are trimmed.
4210//         channel_a
4211//             .update(cx_a, |channel, cx| {
4212//                 channel
4213//                     .send_message("\n surrounded by whitespace  \n".to_string(), cx)
4214//                     .unwrap()
4215//             })
4216//             .await
4217//             .unwrap();
4218//         assert_eq!(
4219//             db.get_channel_messages(channel_id, 10, None)
4220//                 .await
4221//                 .unwrap()
4222//                 .iter()
4223//                 .map(|m| &m.body)
4224//                 .collect::<Vec<_>>(),
4225//             &["surrounded by whitespace"]
4226//         );
4227//     }
4228
4229//     #[gpui::test(iterations = 10)]
4230//     async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
4231//         cx_a.foreground().forbid_parking();
4232
4233//         // Connect to a server as 2 clients.
4234//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4235//         let client_a = server.create_client(cx_a, "user_a").await;
4236//         let client_b = server.create_client(cx_b, "user_b").await;
4237//         let mut status_b = client_b.status();
4238
4239//         // Create an org that includes these 2 users.
4240//         let db = &server.app_state.db;
4241//         let org_id = db.create_org("Test Org", "test-org").await.unwrap();
4242//         db.add_org_member(org_id, client_a.current_user_id(&cx_a), false)
4243//             .await
4244//             .unwrap();
4245//         db.add_org_member(org_id, client_b.current_user_id(&cx_b), false)
4246//             .await
4247//             .unwrap();
4248
4249//         // Create a channel that includes all the users.
4250//         let channel_id = db.create_org_channel(org_id, "test-channel").await.unwrap();
4251//         db.add_channel_member(channel_id, client_a.current_user_id(&cx_a), false)
4252//             .await
4253//             .unwrap();
4254//         db.add_channel_member(channel_id, client_b.current_user_id(&cx_b), false)
4255//             .await
4256//             .unwrap();
4257//         db.create_channel_message(
4258//             channel_id,
4259//             client_b.current_user_id(&cx_b),
4260//             "hello A, it's B.",
4261//             OffsetDateTime::now_utc(),
4262//             2,
4263//         )
4264//         .await
4265//         .unwrap();
4266
4267//         let channels_a = cx_a
4268//             .add_model(|cx| ChannelList::new(client_a.user_store.clone(), client_a.clone(), cx));
4269//         channels_a
4270//             .condition(cx_a, |list, _| list.available_channels().is_some())
4271//             .await;
4272
4273//         channels_a.read_with(cx_a, |list, _| {
4274//             assert_eq!(
4275//                 list.available_channels().unwrap(),
4276//                 &[ChannelDetails {
4277//                     id: channel_id.to_proto(),
4278//                     name: "test-channel".to_string()
4279//                 }]
4280//             )
4281//         });
4282//         let channel_a = channels_a.update(cx_a, |this, cx| {
4283//             this.get_channel(channel_id.to_proto(), cx).unwrap()
4284//         });
4285//         channel_a.read_with(cx_a, |channel, _| assert!(channel.messages().is_empty()));
4286//         channel_a
4287//             .condition(&cx_a, |channel, _| {
4288//                 channel_messages(channel)
4289//                     == [("user_b".to_string(), "hello A, it's B.".to_string(), false)]
4290//             })
4291//             .await;
4292
4293//         let channels_b = cx_b
4294//             .add_model(|cx| ChannelList::new(client_b.user_store.clone(), client_b.clone(), cx));
4295//         channels_b
4296//             .condition(cx_b, |list, _| list.available_channels().is_some())
4297//             .await;
4298//         channels_b.read_with(cx_b, |list, _| {
4299//             assert_eq!(
4300//                 list.available_channels().unwrap(),
4301//                 &[ChannelDetails {
4302//                     id: channel_id.to_proto(),
4303//                     name: "test-channel".to_string()
4304//                 }]
4305//             )
4306//         });
4307
4308//         let channel_b = channels_b.update(cx_b, |this, cx| {
4309//             this.get_channel(channel_id.to_proto(), cx).unwrap()
4310//         });
4311//         channel_b.read_with(cx_b, |channel, _| assert!(channel.messages().is_empty()));
4312//         channel_b
4313//             .condition(&cx_b, |channel, _| {
4314//                 channel_messages(channel)
4315//                     == [("user_b".to_string(), "hello A, it's B.".to_string(), false)]
4316//             })
4317//             .await;
4318
4319//         // Disconnect client B, ensuring we can still access its cached channel data.
4320//         server.forbid_connections();
4321//         server.disconnect_client(client_b.current_user_id(&cx_b));
4322//         cx_b.foreground().advance_clock(Duration::from_secs(3));
4323//         while !matches!(
4324//             status_b.next().await,
4325//             Some(client::Status::ReconnectionError { .. })
4326//         ) {}
4327
4328//         channels_b.read_with(cx_b, |channels, _| {
4329//             assert_eq!(
4330//                 channels.available_channels().unwrap(),
4331//                 [ChannelDetails {
4332//                     id: channel_id.to_proto(),
4333//                     name: "test-channel".to_string()
4334//                 }]
4335//             )
4336//         });
4337//         channel_b.read_with(cx_b, |channel, _| {
4338//             assert_eq!(
4339//                 channel_messages(channel),
4340//                 [("user_b".to_string(), "hello A, it's B.".to_string(), false)]
4341//             )
4342//         });
4343
4344//         // Send a message from client B while it is disconnected.
4345//         channel_b
4346//             .update(cx_b, |channel, cx| {
4347//                 let task = channel
4348//                     .send_message("can you see this?".to_string(), cx)
4349//                     .unwrap();
4350//                 assert_eq!(
4351//                     channel_messages(channel),
4352//                     &[
4353//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4354//                         ("user_b".to_string(), "can you see this?".to_string(), true)
4355//                     ]
4356//                 );
4357//                 task
4358//             })
4359//             .await
4360//             .unwrap_err();
4361
4362//         // Send a message from client A while B is disconnected.
4363//         channel_a
4364//             .update(cx_a, |channel, cx| {
4365//                 channel
4366//                     .send_message("oh, hi B.".to_string(), cx)
4367//                     .unwrap()
4368//                     .detach();
4369//                 let task = channel.send_message("sup".to_string(), cx).unwrap();
4370//                 assert_eq!(
4371//                     channel_messages(channel),
4372//                     &[
4373//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4374//                         ("user_a".to_string(), "oh, hi B.".to_string(), true),
4375//                         ("user_a".to_string(), "sup".to_string(), true)
4376//                     ]
4377//                 );
4378//                 task
4379//             })
4380//             .await
4381//             .unwrap();
4382
4383//         // Give client B a chance to reconnect.
4384//         server.allow_connections();
4385//         cx_b.foreground().advance_clock(Duration::from_secs(10));
4386
4387//         // Verify that B sees the new messages upon reconnection, as well as the message client B
4388//         // sent while offline.
4389//         channel_b
4390//             .condition(&cx_b, |channel, _| {
4391//                 channel_messages(channel)
4392//                     == [
4393//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4394//                         ("user_a".to_string(), "oh, hi B.".to_string(), false),
4395//                         ("user_a".to_string(), "sup".to_string(), false),
4396//                         ("user_b".to_string(), "can you see this?".to_string(), false),
4397//                     ]
4398//             })
4399//             .await;
4400
4401//         // Ensure client A and B can communicate normally after reconnection.
4402//         channel_a
4403//             .update(cx_a, |channel, cx| {
4404//                 channel.send_message("you online?".to_string(), cx).unwrap()
4405//             })
4406//             .await
4407//             .unwrap();
4408//         channel_b
4409//             .condition(&cx_b, |channel, _| {
4410//                 channel_messages(channel)
4411//                     == [
4412//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4413//                         ("user_a".to_string(), "oh, hi B.".to_string(), false),
4414//                         ("user_a".to_string(), "sup".to_string(), false),
4415//                         ("user_b".to_string(), "can you see this?".to_string(), false),
4416//                         ("user_a".to_string(), "you online?".to_string(), false),
4417//                     ]
4418//             })
4419//             .await;
4420
4421//         channel_b
4422//             .update(cx_b, |channel, cx| {
4423//                 channel.send_message("yep".to_string(), cx).unwrap()
4424//             })
4425//             .await
4426//             .unwrap();
4427//         channel_a
4428//             .condition(&cx_a, |channel, _| {
4429//                 channel_messages(channel)
4430//                     == [
4431//                         ("user_b".to_string(), "hello A, it's B.".to_string(), false),
4432//                         ("user_a".to_string(), "oh, hi B.".to_string(), false),
4433//                         ("user_a".to_string(), "sup".to_string(), false),
4434//                         ("user_b".to_string(), "can you see this?".to_string(), false),
4435//                         ("user_a".to_string(), "you online?".to_string(), false),
4436//                         ("user_b".to_string(), "yep".to_string(), false),
4437//                     ]
4438//             })
4439//             .await;
4440//     }
4441
4442//     #[gpui::test(iterations = 10)]
4443//     async fn test_contacts(
4444//         cx_a: &mut TestAppContext,
4445//         cx_b: &mut TestAppContext,
4446//         cx_c: &mut TestAppContext,
4447//     ) {
4448//         cx_a.foreground().forbid_parking();
4449//         let lang_registry = Arc::new(LanguageRegistry::test());
4450//         let fs = FakeFs::new(cx_a.background());
4451
4452//         // Connect to a server as 3 clients.
4453//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4454//         let client_a = server.create_client(cx_a, "user_a").await;
4455//         let client_b = server.create_client(cx_b, "user_b").await;
4456//         let client_c = server.create_client(cx_c, "user_c").await;
4457
4458//         // Share a worktree as client A.
4459//         fs.insert_tree(
4460//             "/a",
4461//             json!({
4462//                 ".zed.toml": r#"collaborators = ["user_b", "user_c"]"#,
4463//             }),
4464//         )
4465//         .await;
4466
4467//         let project_a = cx_a.update(|cx| {
4468//             Project::local(
4469//                 client_a.clone(),
4470//                 client_a.user_store.clone(),
4471//                 lang_registry.clone(),
4472//                 fs.clone(),
4473//                 cx,
4474//             )
4475//         });
4476//         let (worktree_a, _) = project_a
4477//             .update(cx_a, |p, cx| {
4478//                 p.find_or_create_local_worktree("/a", true, cx)
4479//             })
4480//             .await
4481//             .unwrap();
4482//         worktree_a
4483//             .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
4484//             .await;
4485
4486//         client_a
4487//             .user_store
4488//             .condition(&cx_a, |user_store, _| {
4489//                 contacts(user_store) == vec![("user_a", vec![("a", false, vec![])])]
4490//             })
4491//             .await;
4492//         client_b
4493//             .user_store
4494//             .condition(&cx_b, |user_store, _| {
4495//                 contacts(user_store) == vec![("user_a", vec![("a", false, vec![])])]
4496//             })
4497//             .await;
4498//         client_c
4499//             .user_store
4500//             .condition(&cx_c, |user_store, _| {
4501//                 contacts(user_store) == vec![("user_a", vec![("a", false, vec![])])]
4502//             })
4503//             .await;
4504
4505//         let project_id = project_a
4506//             .update(cx_a, |project, _| project.next_remote_id())
4507//             .await;
4508//         project_a
4509//             .update(cx_a, |project, cx| project.share(cx))
4510//             .await
4511//             .unwrap();
4512//         client_a
4513//             .user_store
4514//             .condition(&cx_a, |user_store, _| {
4515//                 contacts(user_store) == vec![("user_a", vec![("a", true, vec![])])]
4516//             })
4517//             .await;
4518//         client_b
4519//             .user_store
4520//             .condition(&cx_b, |user_store, _| {
4521//                 contacts(user_store) == vec![("user_a", vec![("a", true, vec![])])]
4522//             })
4523//             .await;
4524//         client_c
4525//             .user_store
4526//             .condition(&cx_c, |user_store, _| {
4527//                 contacts(user_store) == vec![("user_a", vec![("a", true, vec![])])]
4528//             })
4529//             .await;
4530
4531//         let _project_b = Project::remote(
4532//             project_id,
4533//             client_b.clone(),
4534//             client_b.user_store.clone(),
4535//             lang_registry.clone(),
4536//             fs.clone(),
4537//             &mut cx_b.to_async(),
4538//         )
4539//         .await
4540//         .unwrap();
4541
4542//         client_a
4543//             .user_store
4544//             .condition(&cx_a, |user_store, _| {
4545//                 contacts(user_store) == vec![("user_a", vec![("a", true, vec!["user_b"])])]
4546//             })
4547//             .await;
4548//         client_b
4549//             .user_store
4550//             .condition(&cx_b, |user_store, _| {
4551//                 contacts(user_store) == vec![("user_a", vec![("a", true, vec!["user_b"])])]
4552//             })
4553//             .await;
4554//         client_c
4555//             .user_store
4556//             .condition(&cx_c, |user_store, _| {
4557//                 contacts(user_store) == vec![("user_a", vec![("a", true, vec!["user_b"])])]
4558//             })
4559//             .await;
4560
4561//         project_a
4562//             .condition(&cx_a, |project, _| {
4563//                 project.collaborators().contains_key(&client_b.peer_id)
4564//             })
4565//             .await;
4566
4567//         cx_a.update(move |_| drop(project_a));
4568//         client_a
4569//             .user_store
4570//             .condition(&cx_a, |user_store, _| contacts(user_store) == vec![])
4571//             .await;
4572//         client_b
4573//             .user_store
4574//             .condition(&cx_b, |user_store, _| contacts(user_store) == vec![])
4575//             .await;
4576//         client_c
4577//             .user_store
4578//             .condition(&cx_c, |user_store, _| contacts(user_store) == vec![])
4579//             .await;
4580
4581//         fn contacts(user_store: &UserStore) -> Vec<(&str, Vec<(&str, bool, Vec<&str>)>)> {
4582//             user_store
4583//                 .contacts()
4584//                 .iter()
4585//                 .map(|contact| {
4586//                     let worktrees = contact
4587//                         .projects
4588//                         .iter()
4589//                         .map(|p| {
4590//                             (
4591//                                 p.worktree_root_names[0].as_str(),
4592//                                 p.is_shared,
4593//                                 p.guests.iter().map(|p| p.github_login.as_str()).collect(),
4594//                             )
4595//                         })
4596//                         .collect();
4597//                     (contact.user.github_login.as_str(), worktrees)
4598//                 })
4599//                 .collect()
4600//         }
4601//     }
4602
4603//     #[gpui::test(iterations = 10)]
4604//     async fn test_following(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
4605//         cx_a.foreground().forbid_parking();
4606//         let fs = FakeFs::new(cx_a.background());
4607
4608//         // 2 clients connect to a server.
4609//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4610//         let mut client_a = server.create_client(cx_a, "user_a").await;
4611//         let mut client_b = server.create_client(cx_b, "user_b").await;
4612//         cx_a.update(editor::init);
4613//         cx_b.update(editor::init);
4614
4615//         // Client A shares a project.
4616//         fs.insert_tree(
4617//             "/a",
4618//             json!({
4619//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
4620//                 "1.txt": "one",
4621//                 "2.txt": "two",
4622//                 "3.txt": "three",
4623//             }),
4624//         )
4625//         .await;
4626//         let (project_a, worktree_id) = client_a.build_local_project(fs.clone(), "/a", cx_a).await;
4627//         project_a
4628//             .update(cx_a, |project, cx| project.share(cx))
4629//             .await
4630//             .unwrap();
4631
4632//         // Client B joins the project.
4633//         let project_b = client_b
4634//             .build_remote_project(
4635//                 project_a
4636//                     .read_with(cx_a, |project, _| project.remote_id())
4637//                     .unwrap(),
4638//                 cx_b,
4639//             )
4640//             .await;
4641
4642//         // Client A opens some editors.
4643//         let workspace_a = client_a.build_workspace(&project_a, cx_a);
4644//         let pane_a = workspace_a.read_with(cx_a, |workspace, _| workspace.active_pane().clone());
4645//         let editor_a1 = workspace_a
4646//             .update(cx_a, |workspace, cx| {
4647//                 workspace.open_path((worktree_id, "1.txt"), cx)
4648//             })
4649//             .await
4650//             .unwrap()
4651//             .downcast::<Editor>()
4652//             .unwrap();
4653//         let editor_a2 = workspace_a
4654//             .update(cx_a, |workspace, cx| {
4655//                 workspace.open_path((worktree_id, "2.txt"), cx)
4656//             })
4657//             .await
4658//             .unwrap()
4659//             .downcast::<Editor>()
4660//             .unwrap();
4661
4662//         // Client B opens an editor.
4663//         let workspace_b = client_b.build_workspace(&project_b, cx_b);
4664//         let editor_b1 = workspace_b
4665//             .update(cx_b, |workspace, cx| {
4666//                 workspace.open_path((worktree_id, "1.txt"), cx)
4667//             })
4668//             .await
4669//             .unwrap()
4670//             .downcast::<Editor>()
4671//             .unwrap();
4672
4673//         let client_a_id = project_b.read_with(cx_b, |project, _| {
4674//             project.collaborators().values().next().unwrap().peer_id
4675//         });
4676//         let client_b_id = project_a.read_with(cx_a, |project, _| {
4677//             project.collaborators().values().next().unwrap().peer_id
4678//         });
4679
4680//         // When client B starts following client A, all visible view states are replicated to client B.
4681//         editor_a1.update(cx_a, |editor, cx| editor.select_ranges([0..1], None, cx));
4682//         editor_a2.update(cx_a, |editor, cx| editor.select_ranges([2..3], None, cx));
4683//         workspace_b
4684//             .update(cx_b, |workspace, cx| {
4685//                 workspace
4686//                     .toggle_follow(&ToggleFollow(client_a_id), cx)
4687//                     .unwrap()
4688//             })
4689//             .await
4690//             .unwrap();
4691//         let editor_b2 = workspace_b.read_with(cx_b, |workspace, cx| {
4692//             workspace
4693//                 .active_item(cx)
4694//                 .unwrap()
4695//                 .downcast::<Editor>()
4696//                 .unwrap()
4697//         });
4698//         assert!(cx_b.read(|cx| editor_b2.is_focused(cx)));
4699//         assert_eq!(
4700//             editor_b2.read_with(cx_b, |editor, cx| editor.project_path(cx)),
4701//             Some((worktree_id, "2.txt").into())
4702//         );
4703//         assert_eq!(
4704//             editor_b2.read_with(cx_b, |editor, cx| editor.selected_ranges(cx)),
4705//             vec![2..3]
4706//         );
4707//         assert_eq!(
4708//             editor_b1.read_with(cx_b, |editor, cx| editor.selected_ranges(cx)),
4709//             vec![0..1]
4710//         );
4711
4712//         // When client A activates a different editor, client B does so as well.
4713//         workspace_a.update(cx_a, |workspace, cx| {
4714//             workspace.activate_item(&editor_a1, cx)
4715//         });
4716//         workspace_b
4717//             .condition(cx_b, |workspace, cx| {
4718//                 workspace.active_item(cx).unwrap().id() == editor_b1.id()
4719//             })
4720//             .await;
4721
4722//         // When client A navigates back and forth, client B does so as well.
4723//         workspace_a
4724//             .update(cx_a, |workspace, cx| {
4725//                 workspace::Pane::go_back(workspace, None, cx)
4726//             })
4727//             .await;
4728//         workspace_b
4729//             .condition(cx_b, |workspace, cx| {
4730//                 workspace.active_item(cx).unwrap().id() == editor_b2.id()
4731//             })
4732//             .await;
4733
4734//         workspace_a
4735//             .update(cx_a, |workspace, cx| {
4736//                 workspace::Pane::go_forward(workspace, None, cx)
4737//             })
4738//             .await;
4739//         workspace_b
4740//             .condition(cx_b, |workspace, cx| {
4741//                 workspace.active_item(cx).unwrap().id() == editor_b1.id()
4742//             })
4743//             .await;
4744
4745//         // Changes to client A's editor are reflected on client B.
4746//         editor_a1.update(cx_a, |editor, cx| {
4747//             editor.select_ranges([1..1, 2..2], None, cx);
4748//         });
4749//         editor_b1
4750//             .condition(cx_b, |editor, cx| {
4751//                 editor.selected_ranges(cx) == vec![1..1, 2..2]
4752//             })
4753//             .await;
4754
4755//         editor_a1.update(cx_a, |editor, cx| editor.set_text("TWO", cx));
4756//         editor_b1
4757//             .condition(cx_b, |editor, cx| editor.text(cx) == "TWO")
4758//             .await;
4759
4760//         editor_a1.update(cx_a, |editor, cx| {
4761//             editor.select_ranges([3..3], None, cx);
4762//             editor.set_scroll_position(vec2f(0., 100.), cx);
4763//         });
4764//         editor_b1
4765//             .condition(cx_b, |editor, cx| editor.selected_ranges(cx) == vec![3..3])
4766//             .await;
4767
4768//         // After unfollowing, client B stops receiving updates from client A.
4769//         workspace_b.update(cx_b, |workspace, cx| {
4770//             workspace.unfollow(&workspace.active_pane().clone(), cx)
4771//         });
4772//         workspace_a.update(cx_a, |workspace, cx| {
4773//             workspace.activate_item(&editor_a2, cx)
4774//         });
4775//         cx_a.foreground().run_until_parked();
4776//         assert_eq!(
4777//             workspace_b.read_with(cx_b, |workspace, cx| workspace
4778//                 .active_item(cx)
4779//                 .unwrap()
4780//                 .id()),
4781//             editor_b1.id()
4782//         );
4783
4784//         // Client A starts following client B.
4785//         workspace_a
4786//             .update(cx_a, |workspace, cx| {
4787//                 workspace
4788//                     .toggle_follow(&ToggleFollow(client_b_id), cx)
4789//                     .unwrap()
4790//             })
4791//             .await
4792//             .unwrap();
4793//         assert_eq!(
4794//             workspace_a.read_with(cx_a, |workspace, _| workspace.leader_for_pane(&pane_a)),
4795//             Some(client_b_id)
4796//         );
4797//         assert_eq!(
4798//             workspace_a.read_with(cx_a, |workspace, cx| workspace
4799//                 .active_item(cx)
4800//                 .unwrap()
4801//                 .id()),
4802//             editor_a1.id()
4803//         );
4804
4805//         // Following interrupts when client B disconnects.
4806//         client_b.disconnect(&cx_b.to_async()).unwrap();
4807//         cx_a.foreground().run_until_parked();
4808//         assert_eq!(
4809//             workspace_a.read_with(cx_a, |workspace, _| workspace.leader_for_pane(&pane_a)),
4810//             None
4811//         );
4812//     }
4813
4814//     #[gpui::test(iterations = 10)]
4815//     async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
4816//         cx_a.foreground().forbid_parking();
4817//         let fs = FakeFs::new(cx_a.background());
4818
4819//         // 2 clients connect to a server.
4820//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4821//         let mut client_a = server.create_client(cx_a, "user_a").await;
4822//         let mut client_b = server.create_client(cx_b, "user_b").await;
4823//         cx_a.update(editor::init);
4824//         cx_b.update(editor::init);
4825
4826//         // Client A shares a project.
4827//         fs.insert_tree(
4828//             "/a",
4829//             json!({
4830//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
4831//                 "1.txt": "one",
4832//                 "2.txt": "two",
4833//                 "3.txt": "three",
4834//                 "4.txt": "four",
4835//             }),
4836//         )
4837//         .await;
4838//         let (project_a, worktree_id) = client_a.build_local_project(fs.clone(), "/a", cx_a).await;
4839//         project_a
4840//             .update(cx_a, |project, cx| project.share(cx))
4841//             .await
4842//             .unwrap();
4843
4844//         // Client B joins the project.
4845//         let project_b = client_b
4846//             .build_remote_project(
4847//                 project_a
4848//                     .read_with(cx_a, |project, _| project.remote_id())
4849//                     .unwrap(),
4850//                 cx_b,
4851//             )
4852//             .await;
4853
4854//         // Client A opens some editors.
4855//         let workspace_a = client_a.build_workspace(&project_a, cx_a);
4856//         let pane_a1 = workspace_a.read_with(cx_a, |workspace, _| workspace.active_pane().clone());
4857//         let _editor_a1 = workspace_a
4858//             .update(cx_a, |workspace, cx| {
4859//                 workspace.open_path((worktree_id, "1.txt"), cx)
4860//             })
4861//             .await
4862//             .unwrap()
4863//             .downcast::<Editor>()
4864//             .unwrap();
4865
4866//         // Client B opens an editor.
4867//         let workspace_b = client_b.build_workspace(&project_b, cx_b);
4868//         let pane_b1 = workspace_b.read_with(cx_b, |workspace, _| workspace.active_pane().clone());
4869//         let _editor_b1 = workspace_b
4870//             .update(cx_b, |workspace, cx| {
4871//                 workspace.open_path((worktree_id, "2.txt"), cx)
4872//             })
4873//             .await
4874//             .unwrap()
4875//             .downcast::<Editor>()
4876//             .unwrap();
4877
4878//         // Clients A and B follow each other in split panes
4879//         workspace_a
4880//             .update(cx_a, |workspace, cx| {
4881//                 workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx);
4882//                 assert_ne!(*workspace.active_pane(), pane_a1);
4883//                 let leader_id = *project_a.read(cx).collaborators().keys().next().unwrap();
4884//                 workspace
4885//                     .toggle_follow(&workspace::ToggleFollow(leader_id), cx)
4886//                     .unwrap()
4887//             })
4888//             .await
4889//             .unwrap();
4890//         workspace_b
4891//             .update(cx_b, |workspace, cx| {
4892//                 workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx);
4893//                 assert_ne!(*workspace.active_pane(), pane_b1);
4894//                 let leader_id = *project_b.read(cx).collaborators().keys().next().unwrap();
4895//                 workspace
4896//                     .toggle_follow(&workspace::ToggleFollow(leader_id), cx)
4897//                     .unwrap()
4898//             })
4899//             .await
4900//             .unwrap();
4901
4902//         workspace_a
4903//             .update(cx_a, |workspace, cx| {
4904//                 workspace.activate_next_pane(cx);
4905//                 assert_eq!(*workspace.active_pane(), pane_a1);
4906//                 workspace.open_path((worktree_id, "3.txt"), cx)
4907//             })
4908//             .await
4909//             .unwrap();
4910//         workspace_b
4911//             .update(cx_b, |workspace, cx| {
4912//                 workspace.activate_next_pane(cx);
4913//                 assert_eq!(*workspace.active_pane(), pane_b1);
4914//                 workspace.open_path((worktree_id, "4.txt"), cx)
4915//             })
4916//             .await
4917//             .unwrap();
4918//         cx_a.foreground().run_until_parked();
4919
4920//         // Ensure leader updates don't change the active pane of followers
4921//         workspace_a.read_with(cx_a, |workspace, _| {
4922//             assert_eq!(*workspace.active_pane(), pane_a1);
4923//         });
4924//         workspace_b.read_with(cx_b, |workspace, _| {
4925//             assert_eq!(*workspace.active_pane(), pane_b1);
4926//         });
4927
4928//         // Ensure peers following each other doesn't cause an infinite loop.
4929//         assert_eq!(
4930//             workspace_a.read_with(cx_a, |workspace, cx| workspace
4931//                 .active_item(cx)
4932//                 .unwrap()
4933//                 .project_path(cx)),
4934//             Some((worktree_id, "3.txt").into())
4935//         );
4936//         workspace_a.update(cx_a, |workspace, cx| {
4937//             assert_eq!(
4938//                 workspace.active_item(cx).unwrap().project_path(cx),
4939//                 Some((worktree_id, "3.txt").into())
4940//             );
4941//             workspace.activate_next_pane(cx);
4942//             assert_eq!(
4943//                 workspace.active_item(cx).unwrap().project_path(cx),
4944//                 Some((worktree_id, "4.txt").into())
4945//             );
4946//         });
4947//         workspace_b.update(cx_b, |workspace, cx| {
4948//             assert_eq!(
4949//                 workspace.active_item(cx).unwrap().project_path(cx),
4950//                 Some((worktree_id, "4.txt").into())
4951//             );
4952//             workspace.activate_next_pane(cx);
4953//             assert_eq!(
4954//                 workspace.active_item(cx).unwrap().project_path(cx),
4955//                 Some((worktree_id, "3.txt").into())
4956//             );
4957//         });
4958//     }
4959
4960//     #[gpui::test(iterations = 10)]
4961//     async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
4962//         cx_a.foreground().forbid_parking();
4963//         let fs = FakeFs::new(cx_a.background());
4964
4965//         // 2 clients connect to a server.
4966//         let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
4967//         let mut client_a = server.create_client(cx_a, "user_a").await;
4968//         let mut client_b = server.create_client(cx_b, "user_b").await;
4969//         cx_a.update(editor::init);
4970//         cx_b.update(editor::init);
4971
4972//         // Client A shares a project.
4973//         fs.insert_tree(
4974//             "/a",
4975//             json!({
4976//                 ".zed.toml": r#"collaborators = ["user_b"]"#,
4977//                 "1.txt": "one",
4978//                 "2.txt": "two",
4979//                 "3.txt": "three",
4980//             }),
4981//         )
4982//         .await;
4983//         let (project_a, worktree_id) = client_a.build_local_project(fs.clone(), "/a", cx_a).await;
4984//         project_a
4985//             .update(cx_a, |project, cx| project.share(cx))
4986//             .await
4987//             .unwrap();
4988
4989//         // Client B joins the project.
4990//         let project_b = client_b
4991//             .build_remote_project(
4992//                 project_a
4993//                     .read_with(cx_a, |project, _| project.remote_id())
4994//                     .unwrap(),
4995//                 cx_b,
4996//             )
4997//             .await;
4998
4999//         // Client A opens some editors.
5000//         let workspace_a = client_a.build_workspace(&project_a, cx_a);
5001//         let _editor_a1 = workspace_a
5002//             .update(cx_a, |workspace, cx| {
5003//                 workspace.open_path((worktree_id, "1.txt"), cx)
5004//             })
5005//             .await
5006//             .unwrap()
5007//             .downcast::<Editor>()
5008//             .unwrap();
5009
5010//         // Client B starts following client A.
5011//         let workspace_b = client_b.build_workspace(&project_b, cx_b);
5012//         let pane_b = workspace_b.read_with(cx_b, |workspace, _| workspace.active_pane().clone());
5013//         let leader_id = project_b.read_with(cx_b, |project, _| {
5014//             project.collaborators().values().next().unwrap().peer_id
5015//         });
5016//         workspace_b
5017//             .update(cx_b, |workspace, cx| {
5018//                 workspace
5019//                     .toggle_follow(&ToggleFollow(leader_id), cx)
5020//                     .unwrap()
5021//             })
5022//             .await
5023//             .unwrap();
5024//         assert_eq!(
5025//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5026//             Some(leader_id)
5027//         );
5028//         let editor_b2 = workspace_b.read_with(cx_b, |workspace, cx| {
5029//             workspace
5030//                 .active_item(cx)
5031//                 .unwrap()
5032//                 .downcast::<Editor>()
5033//                 .unwrap()
5034//         });
5035
5036//         // When client B moves, it automatically stops following client A.
5037//         editor_b2.update(cx_b, |editor, cx| editor.move_right(&editor::MoveRight, cx));
5038//         assert_eq!(
5039//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5040//             None
5041//         );
5042
5043//         workspace_b
5044//             .update(cx_b, |workspace, cx| {
5045//                 workspace
5046//                     .toggle_follow(&ToggleFollow(leader_id), cx)
5047//                     .unwrap()
5048//             })
5049//             .await
5050//             .unwrap();
5051//         assert_eq!(
5052//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5053//             Some(leader_id)
5054//         );
5055
5056//         // When client B edits, it automatically stops following client A.
5057//         editor_b2.update(cx_b, |editor, cx| editor.insert("X", cx));
5058//         assert_eq!(
5059//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5060//             None
5061//         );
5062
5063//         workspace_b
5064//             .update(cx_b, |workspace, cx| {
5065//                 workspace
5066//                     .toggle_follow(&ToggleFollow(leader_id), cx)
5067//                     .unwrap()
5068//             })
5069//             .await
5070//             .unwrap();
5071//         assert_eq!(
5072//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5073//             Some(leader_id)
5074//         );
5075
5076//         // When client B scrolls, it automatically stops following client A.
5077//         editor_b2.update(cx_b, |editor, cx| {
5078//             editor.set_scroll_position(vec2f(0., 3.), cx)
5079//         });
5080//         assert_eq!(
5081//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5082//             None
5083//         );
5084
5085//         workspace_b
5086//             .update(cx_b, |workspace, cx| {
5087//                 workspace
5088//                     .toggle_follow(&ToggleFollow(leader_id), cx)
5089//                     .unwrap()
5090//             })
5091//             .await
5092//             .unwrap();
5093//         assert_eq!(
5094//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5095//             Some(leader_id)
5096//         );
5097
5098//         // When client B activates a different pane, it continues following client A in the original pane.
5099//         workspace_b.update(cx_b, |workspace, cx| {
5100//             workspace.split_pane(pane_b.clone(), SplitDirection::Right, cx)
5101//         });
5102//         assert_eq!(
5103//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5104//             Some(leader_id)
5105//         );
5106
5107//         workspace_b.update(cx_b, |workspace, cx| workspace.activate_next_pane(cx));
5108//         assert_eq!(
5109//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5110//             Some(leader_id)
5111//         );
5112
5113//         // When client B activates a different item in the original pane, it automatically stops following client A.
5114//         workspace_b
5115//             .update(cx_b, |workspace, cx| {
5116//                 workspace.open_path((worktree_id, "2.txt"), cx)
5117//             })
5118//             .await
5119//             .unwrap();
5120//         assert_eq!(
5121//             workspace_b.read_with(cx_b, |workspace, _| workspace.leader_for_pane(&pane_b)),
5122//             None
5123//         );
5124//     }
5125
5126//     #[gpui::test(iterations = 100)]
5127//     async fn test_random_collaboration(
5128//         cx: &mut TestAppContext,
5129//         deterministic: Arc<Deterministic>,
5130//         rng: StdRng,
5131//     ) {
5132//         cx.foreground().forbid_parking();
5133//         let max_peers = env::var("MAX_PEERS")
5134//             .map(|i| i.parse().expect("invalid `MAX_PEERS` variable"))
5135//             .unwrap_or(5);
5136//         assert!(max_peers <= 5);
5137
5138//         let max_operations = env::var("OPERATIONS")
5139//             .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
5140//             .unwrap_or(10);
5141
5142//         let rng = Arc::new(Mutex::new(rng));
5143
5144//         let guest_lang_registry = Arc::new(LanguageRegistry::test());
5145//         let host_language_registry = Arc::new(LanguageRegistry::test());
5146
5147//         let fs = FakeFs::new(cx.background());
5148//         fs.insert_tree(
5149//             "/_collab",
5150//             json!({
5151//                 ".zed.toml": r#"collaborators = ["guest-1", "guest-2", "guest-3", "guest-4"]"#
5152//             }),
5153//         )
5154//         .await;
5155
5156//         let mut server = TestServer::start(cx.foreground(), cx.background()).await;
5157//         let mut clients = Vec::new();
5158//         let mut user_ids = Vec::new();
5159//         let mut op_start_signals = Vec::new();
5160//         let files = Arc::new(Mutex::new(Vec::new()));
5161
5162//         let mut next_entity_id = 100000;
5163//         let mut host_cx = TestAppContext::new(
5164//             cx.foreground_platform(),
5165//             cx.platform(),
5166//             deterministic.build_foreground(next_entity_id),
5167//             deterministic.build_background(),
5168//             cx.font_cache(),
5169//             cx.leak_detector(),
5170//             next_entity_id,
5171//         );
5172//         let host = server.create_client(&mut host_cx, "host").await;
5173//         let host_project = host_cx.update(|cx| {
5174//             Project::local(
5175//                 host.client.clone(),
5176//                 host.user_store.clone(),
5177//                 host_language_registry.clone(),
5178//                 fs.clone(),
5179//                 cx,
5180//             )
5181//         });
5182//         let host_project_id = host_project
5183//             .update(&mut host_cx, |p, _| p.next_remote_id())
5184//             .await;
5185
5186//         let (collab_worktree, _) = host_project
5187//             .update(&mut host_cx, |project, cx| {
5188//                 project.find_or_create_local_worktree("/_collab", true, cx)
5189//             })
5190//             .await
5191//             .unwrap();
5192//         collab_worktree
5193//             .read_with(&host_cx, |tree, _| tree.as_local().unwrap().scan_complete())
5194//             .await;
5195//         host_project
5196//             .update(&mut host_cx, |project, cx| project.share(cx))
5197//             .await
5198//             .unwrap();
5199
5200//         // Set up fake language servers.
5201//         let mut language = Language::new(
5202//             LanguageConfig {
5203//                 name: "Rust".into(),
5204//                 path_suffixes: vec!["rs".to_string()],
5205//                 ..Default::default()
5206//             },
5207//             None,
5208//         );
5209//         let _fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
5210//             name: "the-fake-language-server",
5211//             capabilities: lsp::LanguageServer::full_capabilities(),
5212//             initializer: Some(Box::new({
5213//                 let rng = rng.clone();
5214//                 let files = files.clone();
5215//                 let project = host_project.downgrade();
5216//                 move |fake_server: &mut FakeLanguageServer| {
5217//                     fake_server.handle_request::<lsp::request::Completion, _, _>(
5218//                         |_, _| async move {
5219//                             Ok(Some(lsp::CompletionResponse::Array(vec![
5220//                                 lsp::CompletionItem {
5221//                                     text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
5222//                                         range: lsp::Range::new(
5223//                                             lsp::Position::new(0, 0),
5224//                                             lsp::Position::new(0, 0),
5225//                                         ),
5226//                                         new_text: "the-new-text".to_string(),
5227//                                     })),
5228//                                     ..Default::default()
5229//                                 },
5230//                             ])))
5231//                         },
5232//                     );
5233
5234//                     fake_server.handle_request::<lsp::request::CodeActionRequest, _, _>(
5235//                         |_, _| async move {
5236//                             Ok(Some(vec![lsp::CodeActionOrCommand::CodeAction(
5237//                                 lsp::CodeAction {
5238//                                     title: "the-code-action".to_string(),
5239//                                     ..Default::default()
5240//                                 },
5241//                             )]))
5242//                         },
5243//                     );
5244
5245//                     fake_server.handle_request::<lsp::request::PrepareRenameRequest, _, _>(
5246//                         |params, _| async move {
5247//                             Ok(Some(lsp::PrepareRenameResponse::Range(lsp::Range::new(
5248//                                 params.position,
5249//                                 params.position,
5250//                             ))))
5251//                         },
5252//                     );
5253
5254//                     fake_server.handle_request::<lsp::request::GotoDefinition, _, _>({
5255//                         let files = files.clone();
5256//                         let rng = rng.clone();
5257//                         move |_, _| {
5258//                             let files = files.clone();
5259//                             let rng = rng.clone();
5260//                             async move {
5261//                                 let files = files.lock();
5262//                                 let mut rng = rng.lock();
5263//                                 let count = rng.gen_range::<usize, _>(1..3);
5264//                                 let files = (0..count)
5265//                                     .map(|_| files.choose(&mut *rng).unwrap())
5266//                                     .collect::<Vec<_>>();
5267//                                 log::info!("LSP: Returning definitions in files {:?}", &files);
5268//                                 Ok(Some(lsp::GotoDefinitionResponse::Array(
5269//                                     files
5270//                                         .into_iter()
5271//                                         .map(|file| lsp::Location {
5272//                                             uri: lsp::Url::from_file_path(file).unwrap(),
5273//                                             range: Default::default(),
5274//                                         })
5275//                                         .collect(),
5276//                                 )))
5277//                             }
5278//                         }
5279//                     });
5280
5281//                     fake_server.handle_request::<lsp::request::DocumentHighlightRequest, _, _>({
5282//                         let rng = rng.clone();
5283//                         let project = project.clone();
5284//                         move |params, mut cx| {
5285//                             let highlights = if let Some(project) = project.upgrade(&cx) {
5286//                                 project.update(&mut cx, |project, cx| {
5287//                                     let path = params
5288//                                         .text_document_position_params
5289//                                         .text_document
5290//                                         .uri
5291//                                         .to_file_path()
5292//                                         .unwrap();
5293//                                     let (worktree, relative_path) =
5294//                                         project.find_local_worktree(&path, cx)?;
5295//                                     let project_path =
5296//                                         ProjectPath::from((worktree.read(cx).id(), relative_path));
5297//                                     let buffer =
5298//                                         project.get_open_buffer(&project_path, cx)?.read(cx);
5299
5300//                                     let mut highlights = Vec::new();
5301//                                     let highlight_count = rng.lock().gen_range(1..=5);
5302//                                     let mut prev_end = 0;
5303//                                     for _ in 0..highlight_count {
5304//                                         let range =
5305//                                             buffer.random_byte_range(prev_end, &mut *rng.lock());
5306
5307//                                         highlights.push(lsp::DocumentHighlight {
5308//                                             range: range_to_lsp(range.to_point_utf16(buffer)),
5309//                                             kind: Some(lsp::DocumentHighlightKind::READ),
5310//                                         });
5311//                                         prev_end = range.end;
5312//                                     }
5313//                                     Some(highlights)
5314//                                 })
5315//                             } else {
5316//                                 None
5317//                             };
5318//                             async move { Ok(highlights) }
5319//                         }
5320//                     });
5321//                 }
5322//             })),
5323//             ..Default::default()
5324//         });
5325//         host_language_registry.add(Arc::new(language));
5326
5327//         let op_start_signal = futures::channel::mpsc::unbounded();
5328//         user_ids.push(host.current_user_id(&host_cx));
5329//         op_start_signals.push(op_start_signal.0);
5330//         clients.push(host_cx.foreground().spawn(host.simulate_host(
5331//             host_project,
5332//             files,
5333//             op_start_signal.1,
5334//             rng.clone(),
5335//             host_cx,
5336//         )));
5337
5338//         let disconnect_host_at = if rng.lock().gen_bool(0.2) {
5339//             rng.lock().gen_range(0..max_operations)
5340//         } else {
5341//             max_operations
5342//         };
5343//         let mut available_guests = vec![
5344//             "guest-1".to_string(),
5345//             "guest-2".to_string(),
5346//             "guest-3".to_string(),
5347//             "guest-4".to_string(),
5348//         ];
5349//         let mut operations = 0;
5350//         while operations < max_operations {
5351//             if operations == disconnect_host_at {
5352//                 server.disconnect_client(user_ids[0]);
5353//                 cx.foreground().advance_clock(RECEIVE_TIMEOUT);
5354//                 drop(op_start_signals);
5355//                 let mut clients = futures::future::join_all(clients).await;
5356//                 cx.foreground().run_until_parked();
5357
5358//                 let (host, mut host_cx, host_err) = clients.remove(0);
5359//                 if let Some(host_err) = host_err {
5360//                     log::error!("host error - {}", host_err);
5361//                 }
5362//                 host.project
5363//                     .as_ref()
5364//                     .unwrap()
5365//                     .read_with(&host_cx, |project, _| assert!(!project.is_shared()));
5366//                 for (guest, mut guest_cx, guest_err) in clients {
5367//                     if let Some(guest_err) = guest_err {
5368//                         log::error!("{} error - {}", guest.username, guest_err);
5369//                     }
5370//                     let contacts = server
5371//                         .store
5372//                         .read()
5373//                         .await
5374//                         .contacts_for_user(guest.current_user_id(&guest_cx));
5375//                     assert!(!contacts
5376//                         .iter()
5377//                         .flat_map(|contact| &contact.projects)
5378//                         .any(|project| project.id == host_project_id));
5379//                     guest
5380//                         .project
5381//                         .as_ref()
5382//                         .unwrap()
5383//                         .read_with(&guest_cx, |project, _| assert!(project.is_read_only()));
5384//                     guest_cx.update(|_| drop(guest));
5385//                 }
5386//                 host_cx.update(|_| drop(host));
5387
5388//                 return;
5389//             }
5390
5391//             let distribution = rng.lock().gen_range(0..100);
5392//             match distribution {
5393//                 0..=19 if !available_guests.is_empty() => {
5394//                     let guest_ix = rng.lock().gen_range(0..available_guests.len());
5395//                     let guest_username = available_guests.remove(guest_ix);
5396//                     log::info!("Adding new connection for {}", guest_username);
5397//                     next_entity_id += 100000;
5398//                     let mut guest_cx = TestAppContext::new(
5399//                         cx.foreground_platform(),
5400//                         cx.platform(),
5401//                         deterministic.build_foreground(next_entity_id),
5402//                         deterministic.build_background(),
5403//                         cx.font_cache(),
5404//                         cx.leak_detector(),
5405//                         next_entity_id,
5406//                     );
5407//                     let guest = server.create_client(&mut guest_cx, &guest_username).await;
5408//                     let guest_project = Project::remote(
5409//                         host_project_id,
5410//                         guest.client.clone(),
5411//                         guest.user_store.clone(),
5412//                         guest_lang_registry.clone(),
5413//                         FakeFs::new(cx.background()),
5414//                         &mut guest_cx.to_async(),
5415//                     )
5416//                     .await
5417//                     .unwrap();
5418//                     let op_start_signal = futures::channel::mpsc::unbounded();
5419//                     user_ids.push(guest.current_user_id(&guest_cx));
5420//                     op_start_signals.push(op_start_signal.0);
5421//                     clients.push(guest_cx.foreground().spawn(guest.simulate_guest(
5422//                         guest_username.clone(),
5423//                         guest_project,
5424//                         op_start_signal.1,
5425//                         rng.clone(),
5426//                         guest_cx,
5427//                     )));
5428
5429//                     log::info!("Added connection for {}", guest_username);
5430//                     operations += 1;
5431//                 }
5432//                 20..=29 if clients.len() > 1 => {
5433//                     log::info!("Removing guest");
5434//                     let guest_ix = rng.lock().gen_range(1..clients.len());
5435//                     let removed_guest_id = user_ids.remove(guest_ix);
5436//                     let guest = clients.remove(guest_ix);
5437//                     op_start_signals.remove(guest_ix);
5438//                     server.disconnect_client(removed_guest_id);
5439//                     cx.foreground().advance_clock(RECEIVE_TIMEOUT);
5440//                     let (guest, mut guest_cx, guest_err) = guest.await;
5441//                     if let Some(guest_err) = guest_err {
5442//                         log::error!("{} error - {}", guest.username, guest_err);
5443//                     }
5444//                     guest
5445//                         .project
5446//                         .as_ref()
5447//                         .unwrap()
5448//                         .read_with(&guest_cx, |project, _| assert!(project.is_read_only()));
5449//                     for user_id in &user_ids {
5450//                         for contact in server.store.read().await.contacts_for_user(*user_id) {
5451//                             assert_ne!(
5452//                                 contact.user_id, removed_guest_id.0 as u64,
5453//                                 "removed guest is still a contact of another peer"
5454//                             );
5455//                             for project in contact.projects {
5456//                                 for project_guest_id in project.guests {
5457//                                     assert_ne!(
5458//                                         project_guest_id, removed_guest_id.0 as u64,
5459//                                         "removed guest appears as still participating on a project"
5460//                                     );
5461//                                 }
5462//                             }
5463//                         }
5464//                     }
5465
5466//                     log::info!("{} removed", guest.username);
5467//                     available_guests.push(guest.username.clone());
5468//                     guest_cx.update(|_| drop(guest));
5469
5470//                     operations += 1;
5471//                 }
5472//                 _ => {
5473//                     while operations < max_operations && rng.lock().gen_bool(0.7) {
5474//                         op_start_signals
5475//                             .choose(&mut *rng.lock())
5476//                             .unwrap()
5477//                             .unbounded_send(())
5478//                             .unwrap();
5479//                         operations += 1;
5480//                     }
5481
5482//                     if rng.lock().gen_bool(0.8) {
5483//                         cx.foreground().run_until_parked();
5484//                     }
5485//                 }
5486//             }
5487//         }
5488
5489//         drop(op_start_signals);
5490//         let mut clients = futures::future::join_all(clients).await;
5491//         cx.foreground().run_until_parked();
5492
5493//         let (host_client, mut host_cx, host_err) = clients.remove(0);
5494//         if let Some(host_err) = host_err {
5495//             panic!("host error - {}", host_err);
5496//         }
5497//         let host_project = host_client.project.as_ref().unwrap();
5498//         let host_worktree_snapshots = host_project.read_with(&host_cx, |project, cx| {
5499//             project
5500//                 .worktrees(cx)
5501//                 .map(|worktree| {
5502//                     let snapshot = worktree.read(cx).snapshot();
5503//                     (snapshot.id(), snapshot)
5504//                 })
5505//                 .collect::<BTreeMap<_, _>>()
5506//         });
5507
5508//         host_client
5509//             .project
5510//             .as_ref()
5511//             .unwrap()
5512//             .read_with(&host_cx, |project, cx| project.check_invariants(cx));
5513
5514//         for (guest_client, mut guest_cx, guest_err) in clients.into_iter() {
5515//             if let Some(guest_err) = guest_err {
5516//                 panic!("{} error - {}", guest_client.username, guest_err);
5517//             }
5518//             let worktree_snapshots =
5519//                 guest_client
5520//                     .project
5521//                     .as_ref()
5522//                     .unwrap()
5523//                     .read_with(&guest_cx, |project, cx| {
5524//                         project
5525//                             .worktrees(cx)
5526//                             .map(|worktree| {
5527//                                 let worktree = worktree.read(cx);
5528//                                 (worktree.id(), worktree.snapshot())
5529//                             })
5530//                             .collect::<BTreeMap<_, _>>()
5531//                     });
5532
5533//             assert_eq!(
5534//                 worktree_snapshots.keys().collect::<Vec<_>>(),
5535//                 host_worktree_snapshots.keys().collect::<Vec<_>>(),
5536//                 "{} has different worktrees than the host",
5537//                 guest_client.username
5538//             );
5539//             for (id, host_snapshot) in &host_worktree_snapshots {
5540//                 let guest_snapshot = &worktree_snapshots[id];
5541//                 assert_eq!(
5542//                     guest_snapshot.root_name(),
5543//                     host_snapshot.root_name(),
5544//                     "{} has different root name than the host for worktree {}",
5545//                     guest_client.username,
5546//                     id
5547//                 );
5548//                 assert_eq!(
5549//                     guest_snapshot.entries(false).collect::<Vec<_>>(),
5550//                     host_snapshot.entries(false).collect::<Vec<_>>(),
5551//                     "{} has different snapshot than the host for worktree {}",
5552//                     guest_client.username,
5553//                     id
5554//                 );
5555//             }
5556
5557//             guest_client
5558//                 .project
5559//                 .as_ref()
5560//                 .unwrap()
5561//                 .read_with(&guest_cx, |project, cx| project.check_invariants(cx));
5562
5563//             for guest_buffer in &guest_client.buffers {
5564//                 let buffer_id = guest_buffer.read_with(&guest_cx, |buffer, _| buffer.remote_id());
5565//                 let host_buffer = host_project.read_with(&host_cx, |project, cx| {
5566//                     project.buffer_for_id(buffer_id, cx).expect(&format!(
5567//                         "host does not have buffer for guest:{}, peer:{}, id:{}",
5568//                         guest_client.username, guest_client.peer_id, buffer_id
5569//                     ))
5570//                 });
5571//                 let path = host_buffer
5572//                     .read_with(&host_cx, |buffer, cx| buffer.file().unwrap().full_path(cx));
5573
5574//                 assert_eq!(
5575//                     guest_buffer.read_with(&guest_cx, |buffer, _| buffer.deferred_ops_len()),
5576//                     0,
5577//                     "{}, buffer {}, path {:?} has deferred operations",
5578//                     guest_client.username,
5579//                     buffer_id,
5580//                     path,
5581//                 );
5582//                 assert_eq!(
5583//                     guest_buffer.read_with(&guest_cx, |buffer, _| buffer.text()),
5584//                     host_buffer.read_with(&host_cx, |buffer, _| buffer.text()),
5585//                     "{}, buffer {}, path {:?}, differs from the host's buffer",
5586//                     guest_client.username,
5587//                     buffer_id,
5588//                     path
5589//                 );
5590//             }
5591
5592//             guest_cx.update(|_| drop(guest_client));
5593//         }
5594
5595//         host_cx.update(|_| drop(host_client));
5596//     }
5597
5598//     struct TestServer {
5599//         peer: Arc<Peer>,
5600//         app_state: Arc<AppState>,
5601//         server: Arc<Server>,
5602//         foreground: Rc<executor::Foreground>,
5603//         notifications: mpsc::UnboundedReceiver<()>,
5604//         connection_killers: Arc<Mutex<HashMap<UserId, Arc<AtomicBool>>>>,
5605//         forbid_connections: Arc<AtomicBool>,
5606//         _test_db: TestDb,
5607//     }
5608
5609//     impl TestServer {
5610//         async fn start(
5611//             foreground: Rc<executor::Foreground>,
5612//             background: Arc<executor::Background>,
5613//         ) -> Self {
5614//             let test_db = TestDb::fake(background);
5615//             let app_state = Self::build_app_state(&test_db).await;
5616//             let peer = Peer::new();
5617//             let notifications = mpsc::unbounded();
5618//             let server = Server::new(app_state.clone(), peer.clone(), Some(notifications.0));
5619//             Self {
5620//                 peer,
5621//                 app_state,
5622//                 server,
5623//                 foreground,
5624//                 notifications: notifications.1,
5625//                 connection_killers: Default::default(),
5626//                 forbid_connections: Default::default(),
5627//                 _test_db: test_db,
5628//             }
5629//         }
5630
5631//         async fn create_client(&mut self, cx: &mut TestAppContext, name: &str) -> TestClient {
5632//             cx.update(|cx| {
5633//                 let settings = Settings::test(cx);
5634//                 cx.set_global(settings);
5635//             });
5636
5637//             let http = FakeHttpClient::with_404_response();
5638//             let user_id = self.app_state.db.create_user(name, false).await.unwrap();
5639//             let client_name = name.to_string();
5640//             let mut client = Client::new(http.clone());
5641//             let server = self.server.clone();
5642//             let connection_killers = self.connection_killers.clone();
5643//             let forbid_connections = self.forbid_connections.clone();
5644//             let (connection_id_tx, mut connection_id_rx) = mpsc::channel(16);
5645
5646//             Arc::get_mut(&mut client)
5647//                 .unwrap()
5648//                 .override_authenticate(move |cx| {
5649//                     cx.spawn(|_| async move {
5650//                         let access_token = "the-token".to_string();
5651//                         Ok(Credentials {
5652//                             user_id: user_id.0 as u64,
5653//                             access_token,
5654//                         })
5655//                     })
5656//                 })
5657//                 .override_establish_connection(move |credentials, cx| {
5658//                     assert_eq!(credentials.user_id, user_id.0 as u64);
5659//                     assert_eq!(credentials.access_token, "the-token");
5660
5661//                     let server = server.clone();
5662//                     let connection_killers = connection_killers.clone();
5663//                     let forbid_connections = forbid_connections.clone();
5664//                     let client_name = client_name.clone();
5665//                     let connection_id_tx = connection_id_tx.clone();
5666//                     cx.spawn(move |cx| async move {
5667//                         if forbid_connections.load(SeqCst) {
5668//                             Err(EstablishConnectionError::other(anyhow!(
5669//                                 "server is forbidding connections"
5670//                             )))
5671//                         } else {
5672//                             let (client_conn, server_conn, killed) =
5673//                                 Connection::in_memory(cx.background());
5674//                             connection_killers.lock().insert(user_id, killed);
5675//                             cx.background()
5676//                                 .spawn(server.handle_connection(
5677//                                     server_conn,
5678//                                     client_name,
5679//                                     user_id,
5680//                                     Some(connection_id_tx),
5681//                                     cx.background(),
5682//                                 ))
5683//                                 .detach();
5684//                             Ok(client_conn)
5685//                         }
5686//                     })
5687//                 });
5688
5689//             client
5690//                 .authenticate_and_connect(false, &cx.to_async())
5691//                 .await
5692//                 .unwrap();
5693
5694//             Channel::init(&client);
5695//             Project::init(&client);
5696//             cx.update(|cx| {
5697//                 workspace::init(&client, cx);
5698//             });
5699
5700//             let peer_id = PeerId(connection_id_rx.next().await.unwrap().0);
5701//             let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
5702
5703//             let client = TestClient {
5704//                 client,
5705//                 peer_id,
5706//                 username: name.to_string(),
5707//                 user_store,
5708//                 language_registry: Arc::new(LanguageRegistry::test()),
5709//                 project: Default::default(),
5710//                 buffers: Default::default(),
5711//             };
5712//             client.wait_for_current_user(cx).await;
5713//             client
5714//         }
5715
5716//         fn disconnect_client(&self, user_id: UserId) {
5717//             self.connection_killers
5718//                 .lock()
5719//                 .remove(&user_id)
5720//                 .unwrap()
5721//                 .store(true, SeqCst);
5722//         }
5723
5724//         fn forbid_connections(&self) {
5725//             self.forbid_connections.store(true, SeqCst);
5726//         }
5727
5728//         fn allow_connections(&self) {
5729//             self.forbid_connections.store(false, SeqCst);
5730//         }
5731
5732//         async fn build_app_state(test_db: &TestDb) -> Arc<AppState> {
5733//             let mut config = Config::default();
5734//             config.database_url = test_db.url.clone();
5735//             Arc::new(AppState {
5736//                 db: test_db.db().clone(),
5737//                 config,
5738//             })
5739//         }
5740
5741//         async fn state<'a>(&'a self) -> RwLockReadGuard<'a, Store> {
5742//             self.server.store.read().await
5743//         }
5744
5745//         async fn condition<F>(&mut self, mut predicate: F)
5746//         where
5747//             F: FnMut(&Store) -> bool,
5748//         {
5749//             async_std::future::timeout(Duration::from_millis(500), async {
5750//                 while !(predicate)(&*self.server.store.read().await) {
5751//                     self.foreground.start_waiting();
5752//                     self.notifications.next().await;
5753//                     self.foreground.finish_waiting();
5754//                 }
5755//             })
5756//             .await
5757//             .expect("condition timed out");
5758//         }
5759//     }
5760
5761//     impl Deref for TestServer {
5762//         type Target = Server;
5763
5764//         fn deref(&self) -> &Self::Target {
5765//             &self.server
5766//         }
5767//     }
5768
5769//     impl Drop for TestServer {
5770//         fn drop(&mut self) {
5771//             self.peer.reset();
5772//         }
5773//     }
5774
5775//     struct TestClient {
5776//         client: Arc<Client>,
5777//         username: String,
5778//         pub peer_id: PeerId,
5779//         pub user_store: ModelHandle<UserStore>,
5780//         language_registry: Arc<LanguageRegistry>,
5781//         project: Option<ModelHandle<Project>>,
5782//         buffers: HashSet<ModelHandle<language::Buffer>>,
5783//     }
5784
5785//     impl Deref for TestClient {
5786//         type Target = Arc<Client>;
5787
5788//         fn deref(&self) -> &Self::Target {
5789//             &self.client
5790//         }
5791//     }
5792
5793//     impl TestClient {
5794//         pub fn current_user_id(&self, cx: &TestAppContext) -> UserId {
5795//             UserId::from_proto(
5796//                 self.user_store
5797//                     .read_with(cx, |user_store, _| user_store.current_user().unwrap().id),
5798//             )
5799//         }
5800
5801//         async fn wait_for_current_user(&self, cx: &TestAppContext) {
5802//             let mut authed_user = self
5803//                 .user_store
5804//                 .read_with(cx, |user_store, _| user_store.watch_current_user());
5805//             while authed_user.next().await.unwrap().is_none() {}
5806//         }
5807
5808//         async fn build_local_project(
5809//             &mut self,
5810//             fs: Arc<FakeFs>,
5811//             root_path: impl AsRef<Path>,
5812//             cx: &mut TestAppContext,
5813//         ) -> (ModelHandle<Project>, WorktreeId) {
5814//             let project = cx.update(|cx| {
5815//                 Project::local(
5816//                     self.client.clone(),
5817//                     self.user_store.clone(),
5818//                     self.language_registry.clone(),
5819//                     fs,
5820//                     cx,
5821//                 )
5822//             });
5823//             self.project = Some(project.clone());
5824//             let (worktree, _) = project
5825//                 .update(cx, |p, cx| {
5826//                     p.find_or_create_local_worktree(root_path, true, cx)
5827//                 })
5828//                 .await
5829//                 .unwrap();
5830//             worktree
5831//                 .read_with(cx, |tree, _| tree.as_local().unwrap().scan_complete())
5832//                 .await;
5833//             project
5834//                 .update(cx, |project, _| project.next_remote_id())
5835//                 .await;
5836//             (project, worktree.read_with(cx, |tree, _| tree.id()))
5837//         }
5838
5839//         async fn build_remote_project(
5840//             &mut self,
5841//             project_id: u64,
5842//             cx: &mut TestAppContext,
5843//         ) -> ModelHandle<Project> {
5844//             let project = Project::remote(
5845//                 project_id,
5846//                 self.client.clone(),
5847//                 self.user_store.clone(),
5848//                 self.language_registry.clone(),
5849//                 FakeFs::new(cx.background()),
5850//                 &mut cx.to_async(),
5851//             )
5852//             .await
5853//             .unwrap();
5854//             self.project = Some(project.clone());
5855//             project
5856//         }
5857
5858//         fn build_workspace(
5859//             &self,
5860//             project: &ModelHandle<Project>,
5861//             cx: &mut TestAppContext,
5862//         ) -> ViewHandle<Workspace> {
5863//             let (window_id, _) = cx.add_window(|_| EmptyView);
5864//             cx.add_view(window_id, |cx| {
5865//                 let fs = project.read(cx).fs().clone();
5866//                 Workspace::new(
5867//                     &WorkspaceParams {
5868//                         fs,
5869//                         project: project.clone(),
5870//                         user_store: self.user_store.clone(),
5871//                         languages: self.language_registry.clone(),
5872//                         themes: ThemeRegistry::new((), cx.font_cache().clone()),
5873//                         channel_list: cx.add_model(|cx| {
5874//                             ChannelList::new(self.user_store.clone(), self.client.clone(), cx)
5875//                         }),
5876//                         client: self.client.clone(),
5877//                     },
5878//                     cx,
5879//                 )
5880//             })
5881//         }
5882
5883//         async fn simulate_host(
5884//             mut self,
5885//             project: ModelHandle<Project>,
5886//             files: Arc<Mutex<Vec<PathBuf>>>,
5887//             op_start_signal: futures::channel::mpsc::UnboundedReceiver<()>,
5888//             rng: Arc<Mutex<StdRng>>,
5889//             mut cx: TestAppContext,
5890//         ) -> (Self, TestAppContext, Option<anyhow::Error>) {
5891//             async fn simulate_host_internal(
5892//                 client: &mut TestClient,
5893//                 project: ModelHandle<Project>,
5894//                 files: Arc<Mutex<Vec<PathBuf>>>,
5895//                 mut op_start_signal: futures::channel::mpsc::UnboundedReceiver<()>,
5896//                 rng: Arc<Mutex<StdRng>>,
5897//                 cx: &mut TestAppContext,
5898//             ) -> anyhow::Result<()> {
5899//                 let fs = project.read_with(cx, |project, _| project.fs().clone());
5900
5901//                 while op_start_signal.next().await.is_some() {
5902//                     let distribution = rng.lock().gen_range::<usize, _>(0..100);
5903//                     match distribution {
5904//                         0..=20 if !files.lock().is_empty() => {
5905//                             let path = files.lock().choose(&mut *rng.lock()).unwrap().clone();
5906//                             let mut path = path.as_path();
5907//                             while let Some(parent_path) = path.parent() {
5908//                                 path = parent_path;
5909//                                 if rng.lock().gen() {
5910//                                     break;
5911//                                 }
5912//                             }
5913
5914//                             log::info!("Host: find/create local worktree {:?}", path);
5915//                             let find_or_create_worktree = project.update(cx, |project, cx| {
5916//                                 project.find_or_create_local_worktree(path, true, cx)
5917//                             });
5918//                             if rng.lock().gen() {
5919//                                 cx.background().spawn(find_or_create_worktree).detach();
5920//                             } else {
5921//                                 find_or_create_worktree.await?;
5922//                             }
5923//                         }
5924//                         10..=80 if !files.lock().is_empty() => {
5925//                             let buffer = if client.buffers.is_empty() || rng.lock().gen() {
5926//                                 let file = files.lock().choose(&mut *rng.lock()).unwrap().clone();
5927//                                 let (worktree, path) = project
5928//                                     .update(cx, |project, cx| {
5929//                                         project.find_or_create_local_worktree(
5930//                                             file.clone(),
5931//                                             true,
5932//                                             cx,
5933//                                         )
5934//                                     })
5935//                                     .await?;
5936//                                 let project_path =
5937//                                     worktree.read_with(cx, |worktree, _| (worktree.id(), path));
5938//                                 log::info!(
5939//                                     "Host: opening path {:?}, worktree {}, relative_path {:?}",
5940//                                     file,
5941//                                     project_path.0,
5942//                                     project_path.1
5943//                                 );
5944//                                 let buffer = project
5945//                                     .update(cx, |project, cx| project.open_buffer(project_path, cx))
5946//                                     .await
5947//                                     .unwrap();
5948//                                 client.buffers.insert(buffer.clone());
5949//                                 buffer
5950//                             } else {
5951//                                 client
5952//                                     .buffers
5953//                                     .iter()
5954//                                     .choose(&mut *rng.lock())
5955//                                     .unwrap()
5956//                                     .clone()
5957//                             };
5958
5959//                             if rng.lock().gen_bool(0.1) {
5960//                                 cx.update(|cx| {
5961//                                     log::info!(
5962//                                         "Host: dropping buffer {:?}",
5963//                                         buffer.read(cx).file().unwrap().full_path(cx)
5964//                                     );
5965//                                     client.buffers.remove(&buffer);
5966//                                     drop(buffer);
5967//                                 });
5968//                             } else {
5969//                                 buffer.update(cx, |buffer, cx| {
5970//                                     log::info!(
5971//                                         "Host: updating buffer {:?} ({})",
5972//                                         buffer.file().unwrap().full_path(cx),
5973//                                         buffer.remote_id()
5974//                                     );
5975
5976//                                     if rng.lock().gen_bool(0.7) {
5977//                                         buffer.randomly_edit(&mut *rng.lock(), 5, cx);
5978//                                     } else {
5979//                                         buffer.randomly_undo_redo(&mut *rng.lock(), cx);
5980//                                     }
5981//                                 });
5982//                             }
5983//                         }
5984//                         _ => loop {
5985//                             let path_component_count = rng.lock().gen_range::<usize, _>(1..=5);
5986//                             let mut path = PathBuf::new();
5987//                             path.push("/");
5988//                             for _ in 0..path_component_count {
5989//                                 let letter = rng.lock().gen_range(b'a'..=b'z');
5990//                                 path.push(std::str::from_utf8(&[letter]).unwrap());
5991//                             }
5992//                             path.set_extension("rs");
5993//                             let parent_path = path.parent().unwrap();
5994
5995//                             log::info!("Host: creating file {:?}", path,);
5996
5997//                             if fs.create_dir(&parent_path).await.is_ok()
5998//                                 && fs.create_file(&path, Default::default()).await.is_ok()
5999//                             {
6000//                                 files.lock().push(path);
6001//                                 break;
6002//                             } else {
6003//                                 log::info!("Host: cannot create file");
6004//                             }
6005//                         },
6006//                     }
6007
6008//                     cx.background().simulate_random_delay().await;
6009//                 }
6010
6011//                 Ok(())
6012//             }
6013
6014//             let result = simulate_host_internal(
6015//                 &mut self,
6016//                 project.clone(),
6017//                 files,
6018//                 op_start_signal,
6019//                 rng,
6020//                 &mut cx,
6021//             )
6022//             .await;
6023//             log::info!("Host done");
6024//             self.project = Some(project);
6025//             (self, cx, result.err())
6026//         }
6027
6028//         pub async fn simulate_guest(
6029//             mut self,
6030//             guest_username: String,
6031//             project: ModelHandle<Project>,
6032//             op_start_signal: futures::channel::mpsc::UnboundedReceiver<()>,
6033//             rng: Arc<Mutex<StdRng>>,
6034//             mut cx: TestAppContext,
6035//         ) -> (Self, TestAppContext, Option<anyhow::Error>) {
6036//             async fn simulate_guest_internal(
6037//                 client: &mut TestClient,
6038//                 guest_username: &str,
6039//                 project: ModelHandle<Project>,
6040//                 mut op_start_signal: futures::channel::mpsc::UnboundedReceiver<()>,
6041//                 rng: Arc<Mutex<StdRng>>,
6042//                 cx: &mut TestAppContext,
6043//             ) -> anyhow::Result<()> {
6044//                 while op_start_signal.next().await.is_some() {
6045//                     let buffer = if client.buffers.is_empty() || rng.lock().gen() {
6046//                         let worktree = if let Some(worktree) =
6047//                             project.read_with(cx, |project, cx| {
6048//                                 project
6049//                                     .worktrees(&cx)
6050//                                     .filter(|worktree| {
6051//                                         let worktree = worktree.read(cx);
6052//                                         worktree.is_visible()
6053//                                             && worktree.entries(false).any(|e| e.is_file())
6054//                                     })
6055//                                     .choose(&mut *rng.lock())
6056//                             }) {
6057//                             worktree
6058//                         } else {
6059//                             cx.background().simulate_random_delay().await;
6060//                             continue;
6061//                         };
6062
6063//                         let (worktree_root_name, project_path) =
6064//                             worktree.read_with(cx, |worktree, _| {
6065//                                 let entry = worktree
6066//                                     .entries(false)
6067//                                     .filter(|e| e.is_file())
6068//                                     .choose(&mut *rng.lock())
6069//                                     .unwrap();
6070//                                 (
6071//                                     worktree.root_name().to_string(),
6072//                                     (worktree.id(), entry.path.clone()),
6073//                                 )
6074//                             });
6075//                         log::info!(
6076//                             "{}: opening path {:?} in worktree {} ({})",
6077//                             guest_username,
6078//                             project_path.1,
6079//                             project_path.0,
6080//                             worktree_root_name,
6081//                         );
6082//                         let buffer = project
6083//                             .update(cx, |project, cx| {
6084//                                 project.open_buffer(project_path.clone(), cx)
6085//                             })
6086//                             .await?;
6087//                         log::info!(
6088//                             "{}: opened path {:?} in worktree {} ({}) with buffer id {}",
6089//                             guest_username,
6090//                             project_path.1,
6091//                             project_path.0,
6092//                             worktree_root_name,
6093//                             buffer.read_with(cx, |buffer, _| buffer.remote_id())
6094//                         );
6095//                         client.buffers.insert(buffer.clone());
6096//                         buffer
6097//                     } else {
6098//                         client
6099//                             .buffers
6100//                             .iter()
6101//                             .choose(&mut *rng.lock())
6102//                             .unwrap()
6103//                             .clone()
6104//                     };
6105
6106//                     let choice = rng.lock().gen_range(0..100);
6107//                     match choice {
6108//                         0..=9 => {
6109//                             cx.update(|cx| {
6110//                                 log::info!(
6111//                                     "{}: dropping buffer {:?}",
6112//                                     guest_username,
6113//                                     buffer.read(cx).file().unwrap().full_path(cx)
6114//                                 );
6115//                                 client.buffers.remove(&buffer);
6116//                                 drop(buffer);
6117//                             });
6118//                         }
6119//                         10..=19 => {
6120//                             let completions = project.update(cx, |project, cx| {
6121//                                 log::info!(
6122//                                     "{}: requesting completions for buffer {} ({:?})",
6123//                                     guest_username,
6124//                                     buffer.read(cx).remote_id(),
6125//                                     buffer.read(cx).file().unwrap().full_path(cx)
6126//                                 );
6127//                                 let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
6128//                                 project.completions(&buffer, offset, cx)
6129//                             });
6130//                             let completions = cx.background().spawn(async move {
6131//                                 completions
6132//                                     .await
6133//                                     .map_err(|err| anyhow!("completions request failed: {:?}", err))
6134//                             });
6135//                             if rng.lock().gen_bool(0.3) {
6136//                                 log::info!("{}: detaching completions request", guest_username);
6137//                                 cx.update(|cx| completions.detach_and_log_err(cx));
6138//                             } else {
6139//                                 completions.await?;
6140//                             }
6141//                         }
6142//                         20..=29 => {
6143//                             let code_actions = project.update(cx, |project, cx| {
6144//                                 log::info!(
6145//                                     "{}: requesting code actions for buffer {} ({:?})",
6146//                                     guest_username,
6147//                                     buffer.read(cx).remote_id(),
6148//                                     buffer.read(cx).file().unwrap().full_path(cx)
6149//                                 );
6150//                                 let range = buffer.read(cx).random_byte_range(0, &mut *rng.lock());
6151//                                 project.code_actions(&buffer, range, cx)
6152//                             });
6153//                             let code_actions = cx.background().spawn(async move {
6154//                                 code_actions.await.map_err(|err| {
6155//                                     anyhow!("code actions request failed: {:?}", err)
6156//                                 })
6157//                             });
6158//                             if rng.lock().gen_bool(0.3) {
6159//                                 log::info!("{}: detaching code actions request", guest_username);
6160//                                 cx.update(|cx| code_actions.detach_and_log_err(cx));
6161//                             } else {
6162//                                 code_actions.await?;
6163//                             }
6164//                         }
6165//                         30..=39 if buffer.read_with(cx, |buffer, _| buffer.is_dirty()) => {
6166//                             let (requested_version, save) = buffer.update(cx, |buffer, cx| {
6167//                                 log::info!(
6168//                                     "{}: saving buffer {} ({:?})",
6169//                                     guest_username,
6170//                                     buffer.remote_id(),
6171//                                     buffer.file().unwrap().full_path(cx)
6172//                                 );
6173//                                 (buffer.version(), buffer.save(cx))
6174//                             });
6175//                             let save = cx.background().spawn(async move {
6176//                                 let (saved_version, _) = save
6177//                                     .await
6178//                                     .map_err(|err| anyhow!("save request failed: {:?}", err))?;
6179//                                 assert!(saved_version.observed_all(&requested_version));
6180//                                 Ok::<_, anyhow::Error>(())
6181//                             });
6182//                             if rng.lock().gen_bool(0.3) {
6183//                                 log::info!("{}: detaching save request", guest_username);
6184//                                 cx.update(|cx| save.detach_and_log_err(cx));
6185//                             } else {
6186//                                 save.await?;
6187//                             }
6188//                         }
6189//                         40..=44 => {
6190//                             let prepare_rename = project.update(cx, |project, cx| {
6191//                                 log::info!(
6192//                                     "{}: preparing rename for buffer {} ({:?})",
6193//                                     guest_username,
6194//                                     buffer.read(cx).remote_id(),
6195//                                     buffer.read(cx).file().unwrap().full_path(cx)
6196//                                 );
6197//                                 let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
6198//                                 project.prepare_rename(buffer, offset, cx)
6199//                             });
6200//                             let prepare_rename = cx.background().spawn(async move {
6201//                                 prepare_rename.await.map_err(|err| {
6202//                                     anyhow!("prepare rename request failed: {:?}", err)
6203//                                 })
6204//                             });
6205//                             if rng.lock().gen_bool(0.3) {
6206//                                 log::info!("{}: detaching prepare rename request", guest_username);
6207//                                 cx.update(|cx| prepare_rename.detach_and_log_err(cx));
6208//                             } else {
6209//                                 prepare_rename.await?;
6210//                             }
6211//                         }
6212//                         45..=49 => {
6213//                             let definitions = project.update(cx, |project, cx| {
6214//                                 log::info!(
6215//                                     "{}: requesting definitions for buffer {} ({:?})",
6216//                                     guest_username,
6217//                                     buffer.read(cx).remote_id(),
6218//                                     buffer.read(cx).file().unwrap().full_path(cx)
6219//                                 );
6220//                                 let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
6221//                                 project.definition(&buffer, offset, cx)
6222//                             });
6223//                             let definitions = cx.background().spawn(async move {
6224//                                 definitions
6225//                                     .await
6226//                                     .map_err(|err| anyhow!("definitions request failed: {:?}", err))
6227//                             });
6228//                             if rng.lock().gen_bool(0.3) {
6229//                                 log::info!("{}: detaching definitions request", guest_username);
6230//                                 cx.update(|cx| definitions.detach_and_log_err(cx));
6231//                             } else {
6232//                                 client
6233//                                     .buffers
6234//                                     .extend(definitions.await?.into_iter().map(|loc| loc.buffer));
6235//                             }
6236//                         }
6237//                         50..=54 => {
6238//                             let highlights = project.update(cx, |project, cx| {
6239//                                 log::info!(
6240//                                     "{}: requesting highlights for buffer {} ({:?})",
6241//                                     guest_username,
6242//                                     buffer.read(cx).remote_id(),
6243//                                     buffer.read(cx).file().unwrap().full_path(cx)
6244//                                 );
6245//                                 let offset = rng.lock().gen_range(0..=buffer.read(cx).len());
6246//                                 project.document_highlights(&buffer, offset, cx)
6247//                             });
6248//                             let highlights = cx.background().spawn(async move {
6249//                                 highlights
6250//                                     .await
6251//                                     .map_err(|err| anyhow!("highlights request failed: {:?}", err))
6252//                             });
6253//                             if rng.lock().gen_bool(0.3) {
6254//                                 log::info!("{}: detaching highlights request", guest_username);
6255//                                 cx.update(|cx| highlights.detach_and_log_err(cx));
6256//                             } else {
6257//                                 highlights.await?;
6258//                             }
6259//                         }
6260//                         55..=59 => {
6261//                             let search = project.update(cx, |project, cx| {
6262//                                 let query = rng.lock().gen_range('a'..='z');
6263//                                 log::info!("{}: project-wide search {:?}", guest_username, query);
6264//                                 project.search(SearchQuery::text(query, false, false), cx)
6265//                             });
6266//                             let search = cx.background().spawn(async move {
6267//                                 search
6268//                                     .await
6269//                                     .map_err(|err| anyhow!("search request failed: {:?}", err))
6270//                             });
6271//                             if rng.lock().gen_bool(0.3) {
6272//                                 log::info!("{}: detaching search request", guest_username);
6273//                                 cx.update(|cx| search.detach_and_log_err(cx));
6274//                             } else {
6275//                                 client.buffers.extend(search.await?.into_keys());
6276//                             }
6277//                         }
6278//                         _ => {
6279//                             buffer.update(cx, |buffer, cx| {
6280//                                 log::info!(
6281//                                     "{}: updating buffer {} ({:?})",
6282//                                     guest_username,
6283//                                     buffer.remote_id(),
6284//                                     buffer.file().unwrap().full_path(cx)
6285//                                 );
6286//                                 if rng.lock().gen_bool(0.7) {
6287//                                     buffer.randomly_edit(&mut *rng.lock(), 5, cx);
6288//                                 } else {
6289//                                     buffer.randomly_undo_redo(&mut *rng.lock(), cx);
6290//                                 }
6291//                             });
6292//                         }
6293//                     }
6294//                     cx.background().simulate_random_delay().await;
6295//                 }
6296//                 Ok(())
6297//             }
6298
6299//             let result = simulate_guest_internal(
6300//                 &mut self,
6301//                 &guest_username,
6302//                 project.clone(),
6303//                 op_start_signal,
6304//                 rng,
6305//                 &mut cx,
6306//             )
6307//             .await;
6308//             log::info!("{}: done", guest_username);
6309
6310//             self.project = Some(project);
6311//             (self, cx, result.err())
6312//         }
6313//     }
6314
6315//     impl Drop for TestClient {
6316//         fn drop(&mut self) {
6317//             self.client.tear_down();
6318//         }
6319//     }
6320
6321//     impl Executor for Arc<gpui::executor::Background> {
6322//         type Timer = gpui::executor::Timer;
6323
6324//         fn spawn_detached<F: 'static + Send + Future<Output = ()>>(&self, future: F) {
6325//             self.spawn(future).detach();
6326//         }
6327
6328//         fn timer(&self, duration: Duration) -> Self::Timer {
6329//             self.as_ref().timer(duration)
6330//         }
6331//     }
6332
6333//     fn channel_messages(channel: &Channel) -> Vec<(String, String, bool)> {
6334//         channel
6335//             .messages()
6336//             .cursor::<()>()
6337//             .map(|m| {
6338//                 (
6339//                     m.sender.github_login.clone(),
6340//                     m.body.clone(),
6341//                     m.is_pending(),
6342//                 )
6343//             })
6344//             .collect()
6345//     }
6346
6347//     struct EmptyView;
6348
6349//     impl gpui::Entity for EmptyView {
6350//         type Event = ();
6351//     }
6352
6353//     impl gpui::View for EmptyView {
6354//         fn ui_name() -> &'static str {
6355//             "empty view"
6356//         }
6357
6358//         fn render(&mut self, _: &mut gpui::RenderContext<Self>) -> gpui::ElementBox {
6359//             gpui::Element::boxed(gpui::elements::Empty)
6360//         }
6361//     }
6362// }