From bf6ae0d8f8030e832772d63f0195de9284230465 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 14 Feb 2022 11:59:22 -0800 Subject: [PATCH] Restore logic for storing operations on buffers that are still being opened --- crates/project/src/project.rs | 48 ++++++++++++++++++++++++++--------- crates/server/src/rpc.rs | 1 - 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index df339477aa9860adee4721d1b821e59a93807370..40df7cfb9ea00958344120f55dbdf9ecb57c15bc 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -16,8 +16,8 @@ use language::{ point_from_lsp, proto::{deserialize_anchor, serialize_anchor}, range_from_lsp, AnchorRangeExt, Bias, Buffer, CodeAction, Completion, CompletionLabel, - Diagnostic, DiagnosticEntry, File as _, Language, LanguageRegistry, PointUtf16, ToLspPosition, - ToOffset, ToPointUtf16, Transaction, + Diagnostic, DiagnosticEntry, File as _, Language, LanguageRegistry, Operation, PointUtf16, + ToLspPosition, ToOffset, ToPointUtf16, Transaction, }; use lsp::{DiagnosticSeverity, LanguageServer}; use postage::{prelude::Stream, watch}; @@ -46,7 +46,7 @@ pub struct Project { collaborators: HashMap, subscriptions: Vec, language_servers_with_diagnostics_running: isize, - open_buffers: HashMap>, + open_buffers: HashMap, loading_buffers: HashMap< ProjectPath, postage::watch::Receiver, Arc>>>, @@ -54,6 +54,11 @@ pub struct Project { shared_buffers: HashMap>>, } +enum OpenBuffer { + Loaded(WeakModelHandle), + Operations(Vec), +} + enum WorktreeHandle { Strong(ModelHandle), Weak(WeakModelHandle), @@ -737,12 +742,15 @@ impl Project { worktree: Option<&ModelHandle>, cx: &mut ModelContext, ) -> Result<()> { - if self - .open_buffers - .insert(buffer.read(cx).remote_id() as usize, buffer.downgrade()) - .is_some() - { - return Err(anyhow!("registered the same buffer twice")); + match self.open_buffers.insert( + buffer.read(cx).remote_id() as usize, + OpenBuffer::Loaded(buffer.downgrade()), + ) { + None => {} + Some(OpenBuffer::Operations(operations)) => { + buffer.update(cx, |buffer, cx| buffer.apply_ops(operations, cx))? + } + Some(OpenBuffer::Loaded(_)) => Err(anyhow!("registered the same buffer twice"))?, } self.assign_language_to_buffer(&buffer, worktree, cx); Ok(()) @@ -2194,10 +2202,17 @@ impl Project { .into_iter() .map(|op| language::proto::deserialize_operation(op)) .collect::, _>>()?; - if let Some(buffer) = this.open_buffers.get_mut(&buffer_id) { - if let Some(buffer) = buffer.upgrade(cx) { - buffer.update(cx, |buffer, cx| buffer.apply_ops(ops, cx))?; + let buffer = this + .open_buffers + .entry(buffer_id) + .or_insert_with(|| OpenBuffer::Operations(Vec::new())); + match buffer { + OpenBuffer::Loaded(buffer) => { + if let Some(buffer) = buffer.upgrade(cx) { + buffer.update(cx, |buffer, cx| buffer.apply_ops(ops, cx))?; + } } + OpenBuffer::Operations(operations) => operations.extend_from_slice(&ops), } Ok(()) }) @@ -2719,6 +2734,15 @@ impl WorktreeHandle { } } +impl OpenBuffer { + pub fn upgrade(&self, cx: &AppContext) -> Option> { + match self { + OpenBuffer::Loaded(handle) => handle.upgrade(cx), + OpenBuffer::Operations(_) => None, + } + } +} + struct CandidateSet { snapshot: Snapshot, include_ignored: bool, diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index 34ee52b099985e937a9d46a001d76119cb1a25c3..c7aad00e8b39be5b42f970155e6637e560d9484b 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -1082,7 +1082,6 @@ mod tests { github, AppState, Config, }; use ::rpc::Peer; - use async_std::task; use gpui::{executor, ModelHandle, TestAppContext}; use parking_lot::Mutex; use postage::{mpsc, watch};