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