From d00414f81a49501277642868c2cf76eefeb0db6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Thu, 6 May 2021 15:08:59 +0900 Subject: [PATCH] Start moving more LSP calls into callbacks/futures without capturing self --- helix-lsp/src/client.rs | 68 ++++++++++++++++++-------------------- helix-term/src/commands.rs | 4 +-- helix-view/src/editor.rs | 10 ++---- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index c3de4fd76..c54560deb 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -112,49 +112,49 @@ impl Client { R::Result: core::fmt::Debug, // TODO: temporary { // a future that resolves into the response - let future = self.call::(params).await?; - let json = future.await?; + let json = self.call::(params).await?; let response = serde_json::from_value(json)?; Ok(response) } /// Execute a RPC request on the language server. - pub async fn call( + pub fn call( &self, params: R::Params, - ) -> Result>> + ) -> impl Future> where R::Params: serde::Serialize, { - let params = serde_json::to_value(params)?; + let outgoing = self.outgoing.clone(); + let id = self.next_request_id(); - let request = jsonrpc::MethodCall { - jsonrpc: Some(jsonrpc::Version::V2), - id: self.next_request_id(), - method: R::METHOD.to_string(), - params: Self::value_into_params(params), - }; + async move { + let params = serde_json::to_value(params)?; - let (tx, mut rx) = channel::>(1); + let request = jsonrpc::MethodCall { + jsonrpc: Some(jsonrpc::Version::V2), + id, + method: R::METHOD.to_string(), + params: Self::value_into_params(params), + }; - self.outgoing - .send(Payload::Request { - chan: tx, - value: request, - }) - .map_err(|e| Error::Other(e.into()))?; + let (tx, mut rx) = channel::>(1); - use std::time::Duration; - use tokio::time::timeout; + outgoing + .send(Payload::Request { + chan: tx, + value: request, + }) + .map_err(|e| Error::Other(e.into()))?; + + use std::time::Duration; + use tokio::time::timeout; - let future = async move { timeout(Duration::from_secs(2), rx.recv()) .await .map_err(|e| Error::Timeout)? // return Timeout .unwrap() // TODO: None if channel closed - }; - - Ok(future) + } } /// Send a RPC notification to the language server. @@ -269,21 +269,21 @@ impl Client { self.request::(()).await } - pub async fn exit(&self) -> Result<()> { - self.notify::(()).await + pub fn exit(&self) -> impl Future> { + self.notify::(()) } // ------------------------------------------------------------------------------------------- // Text document // ------------------------------------------------------------------------------------------- - pub async fn text_document_did_open( + pub fn text_document_did_open( &self, uri: lsp::Url, version: i32, doc: &Rope, language_id: String, - ) -> Result<()> { + ) -> impl Future> { self.notify::(lsp::DidOpenTextDocumentParams { text_document: lsp::TextDocumentItem { uri, @@ -292,7 +292,6 @@ impl Client { text: String::from(doc), }, }) - .await } pub fn changeset_to_changes( @@ -435,14 +434,13 @@ impl Client { )) } - pub async fn text_document_did_close( + pub fn text_document_did_close( &self, text_document: lsp::TextDocumentIdentifier, - ) -> Result<()> { + ) -> impl Future> { self.notify::(lsp::DidCloseTextDocumentParams { text_document, }) - .await } // will_save / will_save_wait_until @@ -477,11 +475,11 @@ impl Client { .await } - pub async fn completion( + pub fn completion( &self, text_document: lsp::TextDocumentIdentifier, position: lsp::Position, - ) -> Result>> { + ) -> impl Future> { // ) -> Result> { let params = lsp::CompletionParams { text_document_position: lsp::TextDocumentPositionParams { @@ -499,7 +497,7 @@ impl Client { // lsp::CompletionContext { trigger_kind: , trigger_character: Some(), } }; - self.call::(params).await + self.call::(params) } pub async fn text_document_signature_help( diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3292d39f5..1e53d0102 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1790,12 +1790,12 @@ pub fn completion(cx: &mut Context) { ); // TODO: handle fails - let res = block_on(language_server.completion(doc.identifier(), pos)).unwrap(); + let future = language_server.completion(doc.identifier(), pos); let trigger_offset = doc.selection(view.id).cursor(); cx.callback( - res, + future, move |editor: &mut Editor, compositor: &mut Compositor, response: Option| { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 014364e0b..44014e83e 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -131,14 +131,12 @@ impl Editor { .map(ToOwned::to_owned) .unwrap_or_default(); - let rt = tokio::runtime::Handle::current(); - rt.block_on(language_server.text_document_did_open( + tokio::spawn(language_server.text_document_did_open( doc.url().unwrap(), doc.version(), doc.text(), language_id, - )) - .unwrap(); + )); } let id = self.documents.insert(doc); @@ -162,9 +160,7 @@ impl Editor { .and_then(|language| language_servers.get(language)); if let Some(language_server) = language_server { - let rt = tokio::runtime::Handle::current(); - rt.block_on(language_server.text_document_did_close(doc.identifier())) - .unwrap(); + tokio::spawn(language_server.text_document_did_close(doc.identifier())); } // remove selection