summaryrefslogtreecommitdiff
path: root/helix-lsp/src/lib.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-08-31 07:03:06 +0000
committerBlaž Hrastnik2021-09-06 06:25:46 +0000
commitc3a58cdadd8be85b79d773122e807862a3da3a2f (patch)
treeb273ef61b25de933b391f08b5ec7cb660daca792 /helix-lsp/src/lib.rs
parent41f1e8e4fb4b3b387f34ef5d2e913e7ebc7fd888 (diff)
lsp: Refactor capabilities as an async OnceCell
First step in making LSP init asynchronous
Diffstat (limited to 'helix-lsp/src/lib.rs')
-rw-r--r--helix-lsp/src/lib.rs29
1 files changed, 26 insertions, 3 deletions
diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs
index 72606b70..a118239f 100644
--- a/helix-lsp/src/lib.rs
+++ b/helix-lsp/src/lib.rs
@@ -312,17 +312,40 @@ impl Registry {
Entry::Vacant(entry) => {
// initialize a new client
let id = self.counter.fetch_add(1, Ordering::Relaxed);
- let (mut client, incoming) = Client::start(
+ let (client, incoming) = Client::start(
&config.command,
&config.args,
serde_json::from_str(language_config.config.as_deref().unwrap_or("")).ok(),
id,
)?;
- // TODO: run this async without blocking
- futures_executor::block_on(client.initialize())?;
s_incoming.push(UnboundedReceiverStream::new(incoming));
let client = Arc::new(client);
+ let _client = client.clone();
+ let initialize = tokio::spawn(async move {
+ use futures_util::TryFutureExt;
+
+ let value = _client
+ .capabilities
+ .get_or_try_init(|| {
+ _client
+ .initialize()
+ .map_ok(|response| response.capabilities)
+ })
+ .await;
+
+ value.expect("failed to initialize capabilities");
+
+ // next up, notify<initialized>
+ _client
+ .notify::<lsp::notification::Initialized>(lsp::InitializedParams {})
+ .await
+ .unwrap();
+ });
+
+ // TODO: remove this block
+ futures_executor::block_on(initialize).map_err(|_| anyhow::anyhow!("bail"))?;
+
entry.insert((id, client.clone()));
Ok(client)
}