lsp: Move timeouts into client.request

This commit is contained in:
Blaž Hrastnik 2021-01-06 17:48:14 +09:00
parent b2800489de
commit 941c34a7fc
4 changed files with 14 additions and 11 deletions

1
Cargo.lock generated
View File

@ -527,6 +527,7 @@ dependencies = [
"serde_json", "serde_json",
"shellexpand", "shellexpand",
"smol", "smol",
"smol-timeout",
"thiserror", "thiserror",
"url", "url",
] ]

View File

@ -13,6 +13,7 @@ once_cell = "1.4"
lsp-types = { version = "0.86", features = ["proposed"] } lsp-types = { version = "0.86", features = ["proposed"] }
smol = "1.2" smol = "1.2"
smol-timeout = "0.6"
url = "2" url = "2"
pathdiff = "0.2" pathdiff = "0.2"
shellexpand = "2.0" shellexpand = "2.0"

View File

@ -114,7 +114,14 @@ pub async fn request<R: lsp::request::Request>(&self, params: R::Params) -> Resu
.await .await
.map_err(|e| Error::Other(e.into()))?; .map_err(|e| Error::Other(e.into()))?;
let response = rx.recv().await.map_err(|e| Error::Other(e.into()))??; use smol_timeout::TimeoutExt;
use std::time::Duration;
let response = match rx.recv().timeout(Duration::from_secs(2)).await {
Some(response) => response,
None => return Err(Error::Timeout),
}
.map_err(|e| Error::Other(e.into()))??;
let response = serde_json::from_value(response)?; let response = serde_json::from_value(response)?;

View File

@ -857,21 +857,15 @@ pub fn completion(cx: &mut Context) {
let language_server = cx.language_servers.get("rust", &cx.executor).unwrap(); let language_server = cx.language_servers.get("rust", &cx.executor).unwrap();
use log::info; use log::info;
use smol_timeout::TimeoutExt;
use std::time::Duration;
// TODO: blocking here is not ideal // TODO: blocking here is not ideal
let pos = helix_lsp::util::pos_to_lsp_pos( let pos = helix_lsp::util::pos_to_lsp_pos(
&cx.view.doc.text().slice(..), &cx.view.doc.text().slice(..),
cx.view.doc.selection().cursor(), cx.view.doc.selection().cursor(),
); );
let res = smol::block_on(
language_server // TODO: handle fails
.completion(cx.view.doc.identifier(), pos) let res = smol::block_on(language_server.completion(cx.view.doc.identifier(), pos))
.timeout(Duration::from_secs(2)), .unwrap_or_default();
)
.expect("completion failed!")
.unwrap_or_default(); // if timeout, just return
// TODO: if no completion, show some message or something // TODO: if no completion, show some message or something
if !res.is_empty() { if !res.is_empty() {