From 2dcdc61c4da2033e2e937530af6de040bd5df96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20F=C3=B6rster?= Date: Sat, 5 Jun 2021 12:52:33 +0200 Subject: [PATCH] Use work done progress request correctly --- src/features/build.rs | 100 +++++++++++++++++++++++++++--------------- src/server.rs | 14 +++--- 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/src/features/build.rs b/src/features/build.rs index 76755c2a..3146f95a 100644 --- a/src/features/build.rs +++ b/src/features/build.rs @@ -15,12 +15,12 @@ use lsp_types::{ notification::{LogMessage, Progress}, LogMessageParams, NumberOrString, Position, ProgressParams, ProgressParamsValue, TextDocumentIdentifier, TextDocumentPositionParams, WorkDoneProgress, WorkDoneProgressBegin, - WorkDoneProgressEnd, + WorkDoneProgressCreateParams, WorkDoneProgressEnd, }; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; -use crate::{client, Uri}; +use crate::{client, req_queue::ReqQueue, ClientCapabilitiesExt, Uri}; use super::{forward_search, FeatureRequest}; @@ -37,7 +37,6 @@ pub enum BuildStatus { ERROR = 1, FAILURE = 2, CANCELLED = 3, - BUSY = 4, } #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] @@ -46,6 +45,58 @@ pub struct BuildResult { pub status: BuildStatus, } +struct ProgressReporter<'a> { + supports_progress: bool, + req_queue: &'a Mutex, + lsp_sender: Sender, + token: &'a str, +} + +impl<'a> ProgressReporter<'a> { + pub fn start(&self, uri: &Uri) -> Result<()> { + if self.supports_progress { + client::send_request::( + self.req_queue, + &self.lsp_sender, + WorkDoneProgressCreateParams { + token: NumberOrString::String(self.token.to_string()), + }, + )?; + client::send_notification::( + &self.lsp_sender, + ProgressParams { + token: NumberOrString::String(self.token.to_string()), + value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin( + WorkDoneProgressBegin { + title: "Building".to_string(), + message: Some(uri.as_str().to_string()), + cancellable: Some(false), + percentage: None, + }, + )), + }, + )?; + }; + Ok(()) + } +} + +impl<'a> Drop for ProgressReporter<'a> { + fn drop(&mut self) { + if self.supports_progress { + let _ = client::send_notification::( + &self.lsp_sender, + ProgressParams { + token: NumberOrString::String(self.token.to_string()), + value: ProgressParamsValue::WorkDone(WorkDoneProgress::End( + WorkDoneProgressEnd { message: None }, + )), + }, + ); + } + } +} + #[derive(Default)] pub struct BuildEngine { lock: Mutex<()>, @@ -57,6 +108,7 @@ impl BuildEngine { &self, request: FeatureRequest, cancellation_token: &CancellationToken, + req_queue: &Mutex, lsp_sender: &Sender, ) -> Result { let lock = self.lock.lock().unwrap(); @@ -88,30 +140,16 @@ impl BuildEngine { .client_capabilities .lock() .unwrap() - .window - .as_ref() - .and_then(|window| window.work_done_progress) - .unwrap_or_default() + .has_work_done_progress_support() }; - let token = "texlab-build"; - - if supports_progress { - client::send_notification::( - lsp_sender, - ProgressParams { - token: NumberOrString::String(token.to_string()), - value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin( - WorkDoneProgressBegin { - title: "Building".to_string(), - message: Some(document.uri.as_str().to_string()), - cancellable: Some(false), - percentage: None, - }, - )), - }, - )?; - } + let progress_reporter = ProgressReporter { + supports_progress, + req_queue, + lsp_sender: lsp_sender.clone(), + token: "texlab-build", + }; + progress_reporter.start(&document.uri)?; let options = { request.context.options.read().unwrap().clone() }; @@ -146,17 +184,7 @@ impl BuildEngine { BuildStatus::ERROR }; - if supports_progress { - client::send_notification::( - lsp_sender, - ProgressParams { - token: NumberOrString::String(token.to_string()), - value: ProgressParamsValue::WorkDone(WorkDoneProgress::End( - WorkDoneProgressEnd { message: None }, - )), - }, - )?; - } + drop(progress_reporter); drop(lock); if options.build.forward_search_after { diff --git a/src/server.rs b/src/server.rs index cc3b95e0..6806e5f8 100644 --- a/src/server.rs +++ b/src/server.rs @@ -321,10 +321,11 @@ impl Server { }) { let lsp_sender = self.connection.sender.clone(); + let req_queue = Arc::clone(&self.req_queue); let build_engine = Arc::clone(&self.build_engine); self.pool.execute(move || { build_engine - .build(request, CancellationToken::none(), &lsp_sender) + .build(request, CancellationToken::none(), &req_queue, &lsp_sender) .unwrap_or_else(|why| { error!("Build failed: {}", why); BuildResult { @@ -692,10 +693,11 @@ impl Server { ) -> Result<()> { let uri = Arc::new(params.text_document.uri.clone().into()); let lsp_sender = self.connection.sender.clone(); + let req_queue = Arc::clone(&self.req_queue); let build_engine = Arc::clone(&self.build_engine); self.handle_feature_request(id, params, uri, token, move |request, token| { build_engine - .build(request, token, &lsp_sender) + .build(request, token, &req_queue, &lsp_sender) .unwrap_or_else(|why| { error!("Build failed: {}", why); BuildResult { @@ -795,11 +797,9 @@ impl Server { Message::Response(response) => { let mut req_queue = self.req_queue.lock().unwrap(); let data = req_queue.outgoing.complete(response.id); - let result = match response.result { - Some(result) => Ok(result), - None => Err(response - .error - .expect("response without result or error received")), + let result = match response.error { + Some(error) => Err(error), + None => Ok(response.result.unwrap_or_default()), }; data.sender.send(result)?; }