diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 01be8d08df..ecbce24cf1 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -7444,18 +7444,11 @@ async fn test_on_input_format_from_host_to_guest( let fake_language_server = fake_language_servers.next().await.unwrap(); cx_b.foreground().run_until_parked(); - // Type a on type formatting trigger character as the guest. - editor_a.update(cx_a, |editor, cx| { - editor.change_selections(None, cx, |s| s.select_ranges([13..13])); - editor.handle_input(">", cx); - cx.focus(&editor_a); - }); // Receive an OnTypeFormatting request as the host's language server. // Return some formattings from the host's language server. - cx_b.foreground().start_waiting(); - fake_language_server - .handle_request::(|params, _| async move { + fake_language_server.handle_request::( + |params, _| async move { assert_eq!( params.text_document_position.text_document.uri, lsp::Url::from_file_path("/a/main.rs").unwrap(), @@ -7469,18 +7462,27 @@ async fn test_on_input_format_from_host_to_guest( new_text: "~<".to_string(), range: lsp::Range::new(lsp::Position::new(0, 14), lsp::Position::new(0, 14)), }])) - }) - .next() - .await - .unwrap(); - cx_b.foreground().finish_waiting(); + }, + ); + // .next() + // .await + // .unwrap(); // Open the buffer on the guest and see that the formattings worked let buffer_b = project_b .update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)) .await .unwrap(); + + // Type a on type formatting trigger character as the guest. + editor_a.update(cx_a, |editor, cx| { + cx.focus(&editor_a); + editor.change_selections(None, cx, |s| s.select_ranges([13..13])); + editor.handle_input(">", cx); + }); + cx_b.foreground().run_until_parked(); + buffer_b.read_with(cx_b, |buffer, _| { assert_eq!(buffer.text(), "fn main() { a>~< }") }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c0755cf1fe..d944b97124 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2518,8 +2518,6 @@ impl Editor { return None; } - let transaction_title = format!("OnTypeFormatting after {input}"); - let workspace = self.workspace(cx)?; let project = self.project.as_ref()?; let position = self.selections.newest_anchor().head(); let (buffer, buffer_position) = self @@ -2527,20 +2525,11 @@ impl Editor { .read(cx) .text_anchor_for_position(position.clone(), cx)?; let on_type_formatting = project.update(cx, |project, cx| { - project.on_type_format(buffer, buffer_position, input, cx) + project.on_type_format(buffer, buffer_position, input, true, cx) }); Some(cx.spawn(|editor, mut cx| async move { - let project_transaction = on_type_formatting.await?; - Self::open_project_transaction( - &editor, - workspace.downgrade(), - project_transaction, - transaction_title, - cx.clone(), - ) - .await?; - + on_type_formatting.await?; editor.update(&mut cx, |editor, cx| { editor.refresh_document_highlights(cx); })?; diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index 72dc06e14f..5ee6443896 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -12,7 +12,7 @@ use language::{ point_from_lsp, point_to_lsp, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CharKind, CodeAction, - Completion, OffsetRangeExt, PointUtf16, ToOffset, ToPointUtf16, Unclipped, + Completion, OffsetRangeExt, PointUtf16, ToOffset, ToPointUtf16, Transaction, Unclipped, }; use lsp::{DocumentHighlightKind, LanguageServer, LanguageServerId, ServerCapabilities}; use std::{cmp::Reverse, ops::Range, path::Path, sync::Arc}; @@ -1628,7 +1628,7 @@ impl LspCommand for GetCodeActions { #[async_trait(?Send)] impl LspCommand for OnTypeFormatting { - type Response = ProjectTransaction; + type Response = Option; type LspRequest = lsp::request::OnTypeFormatting; type ProtoRequest = proto::OnTypeFormatting; @@ -1668,7 +1668,7 @@ impl LspCommand for OnTypeFormatting { buffer: ModelHandle, server_id: LanguageServerId, mut cx: AsyncAppContext, - ) -> Result { + ) -> Result> { if let Some(edits) = message { let (lsp_adapter, lsp_server) = language_server_for_buffer(&project, &buffer, server_id, &mut cx)?; @@ -1683,7 +1683,7 @@ impl LspCommand for OnTypeFormatting { ) .await } else { - Ok(ProjectTransaction::default()) + Ok(None) } } @@ -1729,33 +1729,27 @@ impl LspCommand for OnTypeFormatting { } fn response_to_proto( - response: ProjectTransaction, - project: &mut Project, - peer_id: PeerId, + response: Option, + _: &mut Project, + _: PeerId, _: &clock::Global, - cx: &mut AppContext, + _: &mut AppContext, ) -> proto::OnTypeFormattingResponse { - let transaction = project.serialize_project_transaction_for_peer(response, peer_id, cx); proto::OnTypeFormattingResponse { - transaction: Some(transaction), + transaction: response + .map(|transaction| language::proto::serialize_transaction(&transaction)), } } async fn response_from_proto( self, message: proto::OnTypeFormattingResponse, - project: ModelHandle, + _: ModelHandle, _: ModelHandle, - mut cx: AsyncAppContext, - ) -> Result { - let message = message - .transaction - .ok_or_else(|| anyhow!("missing transaction"))?; - project - .update(&mut cx, |project, cx| { - project.deserialize_project_transaction(message, self.push_to_history, cx) - }) - .await + _: AsyncAppContext, + ) -> Result> { + let Some(transaction) = message.transaction else { return Ok(None) }; + Ok(Some(language::proto::deserialize_transaction(transaction)?)) } fn buffer_id_from_proto(message: &proto::OnTypeFormatting) -> u64 { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 5df4a94dc0..391a698a1b 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -4040,9 +4040,8 @@ impl Project { buffer: ModelHandle, position: Anchor, trigger: String, - push_to_history: bool, cx: &mut ModelContext, - ) -> Task> { + ) -> Task>> { if self.is_local() { cx.spawn(|this, mut cx| async move { // Do not allow multiple concurrent formatting requests for the @@ -4071,7 +4070,7 @@ impl Project { .await?; this.update(&mut cx, |this, cx| { let position = position.to_point_utf16(buffer.read(cx)); - this.on_type_format(buffer, position, trigger, cx) + this.on_type_format(buffer, position, trigger, false, cx) }) .await }) @@ -4084,16 +4083,13 @@ impl Project { trigger, version: serialize_version(&buffer.read(cx).version()), }; - cx.spawn(|this, mut cx| async move { - let response = client + cx.spawn(|_, _| async move { + client .request(request) .await? .transaction - .ok_or_else(|| anyhow!("missing transaction"))?; - this.update(&mut cx, |this, cx| { - this.deserialize_project_transaction(response, push_to_history, cx) - }) - .await + .map(language::proto::deserialize_transaction) + .transpose() }) } else { Task::ready(Err(anyhow!("project does not have a remote id"))) @@ -4108,7 +4104,7 @@ impl Project { _: Arc, language_server: Arc, cx: &mut AsyncAppContext, - ) -> Result { + ) -> Result> { let edits = this .update(cx, |this, cx| { this.edits_from_lsp( @@ -4139,12 +4135,7 @@ impl Project { } }); - let mut project_transaction = ProjectTransaction::default(); - if let Some(transaction) = transaction { - project_transaction.0.insert(buffer_to_edit, transaction); - } - - Ok(project_transaction) + Ok(transaction) } async fn deserialize_workspace_edit( @@ -4317,8 +4308,9 @@ impl Project { buffer: ModelHandle, position: T, trigger: String, + push_to_history: bool, cx: &mut ModelContext, - ) -> Task> { + ) -> Task>> { let tab_size = buffer.read_with(cx, |buffer, cx| { let language_name = buffer.language().map(|language| language.name()); language_settings(language_name.as_deref(), cx).tab_size @@ -4330,7 +4322,7 @@ impl Project { position, trigger, options: lsp_command::lsp_formatting_options(tab_size.get()).into(), - push_to_history: true, + push_to_history, }, cx, ) @@ -5912,7 +5904,6 @@ impl Project { _: Arc, mut cx: AsyncAppContext, ) -> Result { - let sender_id = envelope.original_sender_id()?; let on_type_formatting = this.update(&mut cx, |this, cx| { let buffer = this .opened_buffers @@ -5928,18 +5919,15 @@ impl Project { buffer, position, envelope.payload.trigger.clone(), - false, cx, )) })?; - let project_transaction = on_type_formatting.await?; - let project_transaction = this.update(&mut cx, |this, cx| { - this.serialize_project_transaction_for_peer(project_transaction, sender_id, cx) - }); - Ok(proto::OnTypeFormattingResponse { - transaction: Some(project_transaction), - }) + let transaction = on_type_formatting + .await? + .as_ref() + .map(language::proto::serialize_transaction); + Ok(proto::OnTypeFormattingResponse { transaction }) } async fn handle_lsp_command( diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 9e0d334944..848cc1c2fa 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -682,7 +682,7 @@ message OnTypeFormatting { } message OnTypeFormattingResponse { - ProjectTransaction transaction = 1; + Transaction transaction = 1; } message PerformRenameResponse { diff --git a/crates/rpc/src/rpc.rs b/crates/rpc/src/rpc.rs index 64fbf19462..b929de9596 100644 --- a/crates/rpc/src/rpc.rs +++ b/crates/rpc/src/rpc.rs @@ -6,4 +6,4 @@ pub use conn::Connection; pub use peer::*; mod macros; -pub const PROTOCOL_VERSION: u32 = 55; +pub const PROTOCOL_VERSION: u32 = 56;