Does async_lsp allow using async?

I'd need to use .await when opening files in LSP because like Cargo my package manager would download dependencies as needed in build commands; my LSP is built around my package manager.

That is the signature of LanguageServer#did_open():

fn did_open(&mut self, params: DidOpenTextDocumentParams) -> ControlFlow<async_lsp::Result<()>> {
    //
}

Since that is not async, I'm wondering whether I'll be able to invoke my asynchronous method inside, since it's not "multi-threaded" (does not implement Send + Sync).

No.

Many functions in this trait return BoxFuture, and you can perform async operations in those. But did_open does not return BoxFuture, so async operations are not possible for that method.

You could call tokio::spawn to spawn a background task that can perform async operations. But you must return from did_open without waiting for it to finish, so you must return a ControlFlow without knowing the result of your async code.

1 Like

Thanks! Makes sense, actually I could emit an event from the background task like in this async_lsp example.

But to be honest, I'm still a bit doubtful whether I'll be able to pass data in this case, from a background task to the foreground task... since my data isn't Send + Sync, so I'm still thinking...

I think I should try to run the LSP server (server.run_buffered(stdin, stdout).await.unwrap();) in parallel with the package manager's build?

OK, I've tried certain things here, but async_lsp is proving to not work for me. I'll have to explore something else...