Use work done progress request correctly

This commit is contained in:
Patrick Förster 2021-06-05 12:52:33 +02:00
parent d664f22b75
commit 2dcdc61c4d
2 changed files with 71 additions and 43 deletions

View file

@ -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<ReqQueue>,
lsp_sender: Sender<lsp_server::Message>,
token: &'a str,
}
impl<'a> ProgressReporter<'a> {
pub fn start(&self, uri: &Uri) -> Result<()> {
if self.supports_progress {
client::send_request::<lsp_types::request::WorkDoneProgressCreate>(
self.req_queue,
&self.lsp_sender,
WorkDoneProgressCreateParams {
token: NumberOrString::String(self.token.to_string()),
},
)?;
client::send_notification::<Progress>(
&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::<Progress>(
&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<BuildParams>,
cancellation_token: &CancellationToken,
req_queue: &Mutex<ReqQueue>,
lsp_sender: &Sender<lsp_server::Message>,
) -> Result<BuildResult> {
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::<Progress>(
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::<Progress>(
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 {

View file

@ -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)?;
}