Move progress reporting to utils
This commit is contained in:
parent
bd903bf132
commit
1893289e5c
@ -21,7 +21,6 @@
|
||||
main_loop::Task,
|
||||
reload::SourceRootConfig,
|
||||
request_metrics::{LatestRequests, RequestMetrics},
|
||||
show_message,
|
||||
thread_pool::TaskPool,
|
||||
to_proto::url_from_abs_path,
|
||||
Result,
|
||||
@ -182,9 +181,6 @@ pub(crate) fn respond(&mut self, response: lsp_server::Response) {
|
||||
self.send(response.into());
|
||||
}
|
||||
}
|
||||
pub(crate) fn show_message(&self, typ: lsp_types::MessageType, message: String) {
|
||||
show_message(typ, message, &self.sender)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GlobalState {
|
||||
|
@ -39,7 +39,7 @@ macro_rules! eprintln {
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
pub type Result<T, E = Box<dyn std::error::Error + Send + Sync>> = std::result::Result<T, E>;
|
||||
pub use crate::{caps::server_capabilities, lsp_utils::show_message, main_loop::main_loop};
|
||||
pub use crate::{caps::server_capabilities, main_loop::main_loop};
|
||||
use std::fmt;
|
||||
|
||||
pub fn from_json<T: DeserializeOwned>(what: &'static str, json: serde_json::Value) -> Result<T> {
|
||||
|
@ -1,24 +1,13 @@
|
||||
//! Utilities for LSP-related boilerplate code.
|
||||
use std::{error::Error, ops::Range};
|
||||
|
||||
use crossbeam_channel::Sender;
|
||||
use lsp_server::{Message, Notification};
|
||||
use lsp_server::Notification;
|
||||
use lsp_types::request::Request;
|
||||
use ra_db::Canceled;
|
||||
use ra_ide::LineIndex;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::from_proto;
|
||||
|
||||
pub fn show_message(
|
||||
typ: lsp_types::MessageType,
|
||||
message: impl Into<String>,
|
||||
sender: &Sender<Message>,
|
||||
) {
|
||||
let message = message.into();
|
||||
let params = lsp_types::ShowMessageParams { typ, message };
|
||||
let not = notification_new::<lsp_types::notification::ShowMessage>(params);
|
||||
sender.send(not.into()).unwrap();
|
||||
}
|
||||
use crate::{from_proto, global_state::GlobalState};
|
||||
|
||||
pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool {
|
||||
e.downcast_ref::<Canceled>().is_some()
|
||||
@ -38,6 +27,74 @@ pub(crate) fn notification_new<N>(params: N::Params) -> Notification
|
||||
Notification::new(N::METHOD.to_string(), params)
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub(crate) enum Progress {
|
||||
Begin,
|
||||
Report,
|
||||
End,
|
||||
}
|
||||
|
||||
impl Progress {
|
||||
pub(crate) fn percentage(done: usize, total: usize) -> f64 {
|
||||
(done as f64 / total.max(1) as f64) * 100.0
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalState {
|
||||
pub(crate) fn show_message(&mut self, typ: lsp_types::MessageType, message: String) {
|
||||
let message = message.into();
|
||||
let params = lsp_types::ShowMessageParams { typ, message };
|
||||
let not = notification_new::<lsp_types::notification::ShowMessage>(params);
|
||||
self.send(not.into());
|
||||
}
|
||||
|
||||
pub(crate) fn report_progress(
|
||||
&mut self,
|
||||
title: &str,
|
||||
state: Progress,
|
||||
message: Option<String>,
|
||||
percentage: Option<f64>,
|
||||
) {
|
||||
if !self.config.client_caps.work_done_progress {
|
||||
return;
|
||||
}
|
||||
let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title));
|
||||
let work_done_progress = match state {
|
||||
Progress::Begin => {
|
||||
let work_done_progress_create = self.req_queue.outgoing.register(
|
||||
lsp_types::request::WorkDoneProgressCreate::METHOD.to_string(),
|
||||
lsp_types::WorkDoneProgressCreateParams { token: token.clone() },
|
||||
|_, _| (),
|
||||
);
|
||||
self.send(work_done_progress_create.into());
|
||||
|
||||
lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
|
||||
title: title.into(),
|
||||
cancellable: None,
|
||||
message,
|
||||
percentage,
|
||||
})
|
||||
}
|
||||
Progress::Report => {
|
||||
lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
|
||||
cancellable: None,
|
||||
message,
|
||||
percentage,
|
||||
})
|
||||
}
|
||||
Progress::End => {
|
||||
lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message })
|
||||
}
|
||||
};
|
||||
let notification =
|
||||
notification_new::<lsp_types::notification::Progress>(lsp_types::ProgressParams {
|
||||
token,
|
||||
value: lsp_types::ProgressParamsValue::WorkDone(work_done_progress),
|
||||
});
|
||||
self.send(notification.into());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn apply_document_changes(
|
||||
old_text: &mut String,
|
||||
content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
|
||||
|
@ -18,7 +18,7 @@
|
||||
from_proto,
|
||||
global_state::{file_id_to_url, url_to_file_id, GlobalState, Status},
|
||||
handlers, lsp_ext,
|
||||
lsp_utils::{apply_document_changes, is_canceled, notification_is, notification_new},
|
||||
lsp_utils::{apply_document_changes, is_canceled, notification_is, notification_new, Progress},
|
||||
Result,
|
||||
};
|
||||
|
||||
@ -181,12 +181,11 @@ fn handle_event(&mut self, event: Event) -> Result<()> {
|
||||
became_ready = true;
|
||||
Progress::End
|
||||
};
|
||||
report_progress(
|
||||
self,
|
||||
self.report_progress(
|
||||
"roots scanned",
|
||||
state,
|
||||
Some(format!("{}/{}", n_done, n_total)),
|
||||
Some(percentage(n_done, n_total)),
|
||||
Some(Progress::percentage(n_done, n_total)),
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -216,7 +215,7 @@ fn handle_event(&mut self, event: Event) -> Result<()> {
|
||||
flycheck::Progress::DidStart => {
|
||||
self.diagnostics.clear_check();
|
||||
(Progress::Begin, None)
|
||||
},
|
||||
}
|
||||
flycheck::Progress::DidCheckCrate(target) => {
|
||||
(Progress::Report, Some(target))
|
||||
}
|
||||
@ -225,7 +224,7 @@ fn handle_event(&mut self, event: Event) -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
report_progress(self, "cargo check", state, message, None);
|
||||
self.report_progress("cargo check", state, message, None);
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -468,60 +467,3 @@ fn update_file_notifications_on_threadpool(&mut self, subscriptions: Vec<FileId>
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum Progress {
|
||||
Begin,
|
||||
Report,
|
||||
End,
|
||||
}
|
||||
|
||||
fn percentage(done: usize, total: usize) -> f64 {
|
||||
(done as f64 / total.max(1) as f64) * 100.0
|
||||
}
|
||||
|
||||
fn report_progress(
|
||||
global_state: &mut GlobalState,
|
||||
title: &str,
|
||||
state: Progress,
|
||||
message: Option<String>,
|
||||
percentage: Option<f64>,
|
||||
) {
|
||||
if !global_state.config.client_caps.work_done_progress {
|
||||
return;
|
||||
}
|
||||
let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title));
|
||||
let work_done_progress = match state {
|
||||
Progress::Begin => {
|
||||
let work_done_progress_create = global_state.req_queue.outgoing.register(
|
||||
lsp_types::request::WorkDoneProgressCreate::METHOD.to_string(),
|
||||
lsp_types::WorkDoneProgressCreateParams { token: token.clone() },
|
||||
|_, _| (),
|
||||
);
|
||||
global_state.send(work_done_progress_create.into());
|
||||
|
||||
lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
|
||||
title: title.into(),
|
||||
cancellable: None,
|
||||
message,
|
||||
percentage,
|
||||
})
|
||||
}
|
||||
Progress::Report => {
|
||||
lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
|
||||
cancellable: None,
|
||||
message,
|
||||
percentage,
|
||||
})
|
||||
}
|
||||
Progress::End => {
|
||||
lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message })
|
||||
}
|
||||
};
|
||||
let notification =
|
||||
notification_new::<lsp_types::notification::Progress>(lsp_types::ProgressParams {
|
||||
token,
|
||||
value: lsp_types::ProgressParamsValue::WorkDone(work_done_progress),
|
||||
});
|
||||
global_state.send(notification.into());
|
||||
}
|
||||
|
@ -36,27 +36,31 @@ pub(crate) fn reload(&mut self) {
|
||||
self.config
|
||||
.linked_projects
|
||||
.iter()
|
||||
.filter_map(|project| match project {
|
||||
.map(|project| match project {
|
||||
LinkedProject::ProjectManifest(manifest) => {
|
||||
ra_project_model::ProjectWorkspace::load(
|
||||
manifest.clone(),
|
||||
&self.config.cargo,
|
||||
self.config.with_sysroot,
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::error!("failed to load workspace: {:#}", err);
|
||||
self.show_message(
|
||||
lsp_types::MessageType::Error,
|
||||
format!("rust-analyzer failed to load workspace: {:#}", err),
|
||||
);
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
LinkedProject::InlineJsonProject(it) => {
|
||||
Some(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
|
||||
Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
.filter_map(|res| {
|
||||
res.map_err(|err| {
|
||||
log::error!("failed to load workspace: {:#}", err);
|
||||
self.show_message(
|
||||
lsp_types::MessageType::Error,
|
||||
format!("rust-analyzer failed to load workspace: {:#}", err),
|
||||
);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
if let FilesWatcher::Client = self.config.files.watcher {
|
||||
|
Loading…
Reference in New Issue
Block a user