Rebuild buffer store to be aware of remote/local distinction (#18303)

Release Notes:

- N/A

---------

Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Conrad Irwin 2024-09-24 15:52:30 -06:00 committed by GitHub
parent da1ef13442
commit c4e0f5e0ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 1127 additions and 826 deletions

View file

@ -3,6 +3,7 @@ use call::ActiveCall;
use fs::{FakeFs, Fs as _}; use fs::{FakeFs, Fs as _};
use gpui::{Context as _, TestAppContext}; use gpui::{Context as _, TestAppContext};
use language::language_settings::all_language_settings; use language::language_settings::all_language_settings;
use project::ProjectPath;
use remote::SshSession; use remote::SshSession;
use remote_server::HeadlessProject; use remote_server::HeadlessProject;
use serde_json::json; use serde_json::json;
@ -108,14 +109,36 @@ async fn test_sharing_an_ssh_remote_project(
}); });
project_b project_b
.update(cx_b, |project, cx| project.save_buffer(buffer_b, cx)) .update(cx_b, |project, cx| {
project.save_buffer_as(
buffer_b.clone(),
ProjectPath {
worktree_id: worktree_id.to_owned(),
path: Arc::from(Path::new("src/renamed.rs")),
},
cx,
)
})
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
remote_fs remote_fs
.load("/code/project1/src/lib.rs".as_ref()) .load("/code/project1/src/renamed.rs".as_ref())
.await .await
.unwrap(), .unwrap(),
"fn one() -> usize { 100 }" "fn one() -> usize { 100 }"
); );
cx_b.run_until_parked();
cx_b.update(|cx| {
assert_eq!(
buffer_b
.read(cx)
.file()
.unwrap()
.path()
.to_string_lossy()
.to_string(),
"src/renamed.rs".to_string()
);
});
} }

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,9 @@
mod signature_help; mod signature_help;
use crate::{ use crate::{
buffer_store::BufferStore, lsp_store::LspStore, CodeAction, CoreCompletion, DocumentHighlight, lsp_store::LspStore, CodeAction, CoreCompletion, DocumentHighlight, Hover, HoverBlock,
Hover, HoverBlock, HoverBlockKind, InlayHint, InlayHintLabel, InlayHintLabelPart, HoverBlockKind, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintLabelPartTooltip,
InlayHintLabelPartTooltip, InlayHintTooltip, Location, LocationLink, MarkupContent, InlayHintTooltip, Location, LocationLink, MarkupContent, ProjectTransaction, ResolveState,
ProjectTransaction, ResolveState,
}; };
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
@ -417,17 +416,17 @@ impl LspCommand for PerformRename {
message: proto::PerformRenameResponse, message: proto::PerformRenameResponse,
lsp_store: Model<LspStore>, lsp_store: Model<LspStore>,
_: Model<Buffer>, _: Model<Buffer>,
cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<ProjectTransaction> { ) -> Result<ProjectTransaction> {
let message = message let message = message
.transaction .transaction
.ok_or_else(|| anyhow!("missing transaction"))?; .ok_or_else(|| anyhow!("missing transaction"))?;
BufferStore::deserialize_project_transaction( lsp_store
lsp_store.read_with(&cx, |lsp_store, _| lsp_store.buffer_store().downgrade())?, .update(&mut cx, |lsp_store, cx| {
message, lsp_store.buffer_store().update(cx, |buffer_store, cx| {
self.push_to_history, buffer_store.deserialize_project_transaction(message, self.push_to_history, cx)
cx, })
) })?
.await .await
} }

View file

@ -1601,18 +1601,18 @@ impl LspStore {
buffer_id: buffer_handle.read(cx).remote_id().into(), buffer_id: buffer_handle.read(cx).remote_id().into(),
action: Some(Self::serialize_code_action(&action)), action: Some(Self::serialize_code_action(&action)),
}; };
cx.spawn(move |this, cx| async move { let buffer_store = self.buffer_store();
cx.spawn(move |_, mut cx| async move {
let response = upstream_client let response = upstream_client
.request(request) .request(request)
.await? .await?
.transaction .transaction
.ok_or_else(|| anyhow!("missing transaction"))?; .ok_or_else(|| anyhow!("missing transaction"))?;
BufferStore::deserialize_project_transaction(
this.read_with(&cx, |this, _| this.buffer_store.downgrade())?, buffer_store
response, .update(&mut cx, |buffer_store, cx| {
push_to_history, buffer_store.deserialize_project_transaction(response, push_to_history, cx)
cx, })?
)
.await .await
}) })
} else { } else {
@ -5062,6 +5062,7 @@ impl LspStore {
.spawn(this.languages.language_for_name(language_name.0.as_ref())) .spawn(this.languages.language_for_name(language_name.0.as_ref()))
.detach(); .detach();
// host
let adapter = this.languages.get_or_register_lsp_adapter( let adapter = this.languages.get_or_register_lsp_adapter(
language_name.clone(), language_name.clone(),
server_name.clone(), server_name.clone(),
@ -5259,7 +5260,8 @@ impl LspStore {
result result
}) })
} else if let Some((client, project_id)) = self.upstream_client() { } else if let Some((client, project_id)) = self.upstream_client() {
cx.spawn(move |this, mut cx| async move { let buffer_store = self.buffer_store();
cx.spawn(move |_, mut cx| async move {
let response = client let response = client
.request(proto::FormatBuffers { .request(proto::FormatBuffers {
project_id, project_id,
@ -5274,12 +5276,11 @@ impl LspStore {
.await? .await?
.transaction .transaction
.ok_or_else(|| anyhow!("missing transaction"))?; .ok_or_else(|| anyhow!("missing transaction"))?;
BufferStore::deserialize_project_transaction(
this.read_with(&cx, |this, _| this.buffer_store.downgrade())?, buffer_store
response, .update(&mut cx, |buffer_store, cx| {
push_to_history, buffer_store.deserialize_project_transaction(response, push_to_history, cx)
cx, })?
)
.await .await
}) })
} else { } else {

View file

@ -1667,16 +1667,8 @@ impl Project {
} }
pub fn create_buffer(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<Model<Buffer>>> { pub fn create_buffer(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<Model<Buffer>>> {
self.buffer_store.update(cx, |buffer_store, cx| { self.buffer_store
buffer_store.create_buffer( .update(cx, |buffer_store, cx| buffer_store.create_buffer(cx))
if self.is_via_collab() {
Some((self.client.clone().into(), self.remote_id().unwrap()))
} else {
None
},
cx,
)
})
} }
pub fn create_local_buffer( pub fn create_local_buffer(
@ -1685,7 +1677,7 @@ impl Project {
language: Option<Arc<Language>>, language: Option<Arc<Language>>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Model<Buffer> { ) -> Model<Buffer> {
if self.is_via_collab() { if self.is_via_collab() || self.is_via_ssh() {
panic!("called create_local_buffer on a remote project") panic!("called create_local_buffer on a remote project")
} }
self.buffer_store.update(cx, |buffer_store, cx| { self.buffer_store.update(cx, |buffer_store, cx| {
@ -3770,7 +3762,9 @@ impl Project {
envelope: TypedEnvelope<proto::OpenNewBuffer>, envelope: TypedEnvelope<proto::OpenNewBuffer>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<proto::OpenBufferResponse> { ) -> Result<proto::OpenBufferResponse> {
let buffer = this.update(&mut cx, |this, cx| this.create_local_buffer("", None, cx))?; let buffer = this
.update(&mut cx, |this, cx| this.create_buffer(cx))?
.await?;
let peer_id = envelope.original_sender_id()?; let peer_id = envelope.original_sender_id()?;
Project::respond_to_open_buffer_request(this, buffer, peer_id, &mut cx) Project::respond_to_open_buffer_request(this, buffer, peer_id, &mut cx)

View file

@ -56,6 +56,7 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test
}) })
.await .await
.unwrap(); .unwrap();
buffer.update(cx, |buffer, cx| { buffer.update(cx, |buffer, cx| {
assert_eq!(buffer.text(), "fn one() -> usize { 1 }"); assert_eq!(buffer.text(), "fn one() -> usize { 1 }");
assert_eq!( assert_eq!(