on master help sign in
Handle language server shutdown with timeout
c2aad85wojciechkepka
helix-lsp/src/client.rs+15
@@ -272,6 +272,21 @@ impl Client {
272 self.notify::<lsp::notification::Exit>(())
272 self.notify::<lsp::notification::Exit>(())
273 }
273 }
274
274
275+ /// Tries to shut down the language server but returns
276+ /// early if server responds with an error.
277+ pub async fn shutdown_and_exit(&self) -> Result<()> {
278+ self.shutdown().await?;
279+ self.exit().await
280+ }
281+
282+ /// Forcefully shuts down the language server ignoring any errors.
283+ pub async fn force_shutdown(&self) -> Result<()> {
284+ if let Err(e) = self.shutdown().await {
285+ log::warn!("language server failed to terminate gracefully - {}", e);
286+ }
287+ self.exit().await
288+ }
289+
275 // -------------------------------------------------------------------------------------------
290 // -------------------------------------------------------------------------------------------
276 // Text document
291 // Text document
277 // -------------------------------------------------------------------------------------------
292 // -------------------------------------------------------------------------------------------
helix-lsp/src/lib.rs+4
@@ -310,6 +310,10 @@ impl Registry {
310 Err(Error::LspNotDefined)
310 Err(Error::LspNotDefined)
311 }
311 }
312 }
312 }
313+
314+ pub fn iter_clients(&self) -> impl Iterator<Item = &Arc<Client>> {
315+ self.inner.values().map(|(_, client)| client)
316+ }
313}
317}
314
318
315#[derive(Debug)]
319#[derive(Debug)]
helix-term/src/application.rs+12−1
@@ -23,7 +23,7 @@ use crossterm::{
23
23
24use tui::layout::Rect;
24use tui::layout::Rect;
25
25
26−use futures_util::stream::FuturesUnordered;
26+use futures_util::{future, stream::FuturesUnordered};
27
27
28type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
28type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
29pub type LspCallback =
29pub type LspCallback =
@@ -406,6 +406,17 @@ impl Application {
406
406
407 self.event_loop().await;
407 self.event_loop().await;
408
408
409+ tokio::time::timeout(
410+ Duration::from_millis(500),
411+ future::join_all(
412+ self.editor
413+ .language_servers
414+ .iter_clients()
415+ .map(|client| client.force_shutdown()),
416+ ),
417+ )
418+ .await;
419+
409 // reset cursor shape
420 // reset cursor shape
410 write!(stdout, "\x1B[2 q");
421 write!(stdout, "\x1B[2 q");
411
422