Auto merge of #13427 - Veykril:cancel-check, r=Veykril
feat: Make flycheck workdone progress reports cancellable In clients that support this (like VSCode), the clients will now render a cancel button on the notification message which can be clicked to cancel the flycheck instead. Closes https://github.com/rust-lang/rust-analyzer/issues/6895 ![Code_VbXgP3SbFD](https://user-images.githubusercontent.com/3757771/196205329-2df93451-c143-4d1b-a700-d988edf55efa.gif)
This commit is contained in:
commit
106285b5c4
@ -87,6 +87,7 @@ impl GlobalState {
|
|||||||
state: Progress,
|
state: Progress,
|
||||||
message: Option<String>,
|
message: Option<String>,
|
||||||
fraction: Option<f64>,
|
fraction: Option<f64>,
|
||||||
|
cancel_token: Option<String>,
|
||||||
) {
|
) {
|
||||||
if !self.config.work_done_progress() {
|
if !self.config.work_done_progress() {
|
||||||
return;
|
return;
|
||||||
@ -95,7 +96,10 @@ impl GlobalState {
|
|||||||
assert!((0.0..=1.0).contains(&f));
|
assert!((0.0..=1.0).contains(&f));
|
||||||
(f * 100.0) as u32
|
(f * 100.0) as u32
|
||||||
});
|
});
|
||||||
let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title));
|
let cancellable = Some(cancel_token.is_some());
|
||||||
|
let token = lsp_types::ProgressToken::String(
|
||||||
|
cancel_token.unwrap_or_else(|| format!("rustAnalyzer/{}", title)),
|
||||||
|
);
|
||||||
let work_done_progress = match state {
|
let work_done_progress = match state {
|
||||||
Progress::Begin => {
|
Progress::Begin => {
|
||||||
self.send_request::<lsp_types::request::WorkDoneProgressCreate>(
|
self.send_request::<lsp_types::request::WorkDoneProgressCreate>(
|
||||||
@ -105,14 +109,14 @@ impl GlobalState {
|
|||||||
|
|
||||||
lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
|
lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
|
||||||
title: title.into(),
|
title: title.into(),
|
||||||
cancellable: None,
|
cancellable,
|
||||||
message,
|
message,
|
||||||
percentage,
|
percentage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Progress::Report => {
|
Progress::Report => {
|
||||||
lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
|
lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
|
||||||
cancellable: None,
|
cancellable,
|
||||||
message,
|
message,
|
||||||
percentage,
|
percentage,
|
||||||
})
|
})
|
||||||
|
@ -257,7 +257,7 @@ impl GlobalState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.report_progress("Indexing", state, message, Some(fraction));
|
self.report_progress("Indexing", state, message, Some(fraction), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Vfs(message) => {
|
Event::Vfs(message) => {
|
||||||
@ -465,7 +465,7 @@ impl GlobalState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.report_progress("Fetching", state, msg, None);
|
self.report_progress("Fetching", state, msg, None, None);
|
||||||
}
|
}
|
||||||
Task::FetchBuildData(progress) => {
|
Task::FetchBuildData(progress) => {
|
||||||
let (state, msg) = match progress {
|
let (state, msg) = match progress {
|
||||||
@ -481,7 +481,7 @@ impl GlobalState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(state) = state {
|
if let Some(state) = state {
|
||||||
self.report_progress("Loading", state, msg, None);
|
self.report_progress("Loading", state, msg, None, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,6 +518,7 @@ impl GlobalState {
|
|||||||
state,
|
state,
|
||||||
Some(format!("{}/{}", n_done, n_total)),
|
Some(format!("{}/{}", n_done, n_total)),
|
||||||
Some(Progress::fraction(n_done, n_total)),
|
Some(Progress::fraction(n_done, n_total)),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -584,7 +585,13 @@ impl GlobalState {
|
|||||||
} else {
|
} else {
|
||||||
format!("cargo check (#{})", id + 1)
|
format!("cargo check (#{})", id + 1)
|
||||||
};
|
};
|
||||||
self.report_progress(&title, state, message, None);
|
self.report_progress(
|
||||||
|
&title,
|
||||||
|
state,
|
||||||
|
message,
|
||||||
|
None,
|
||||||
|
Some(format!("rust-analyzer/checkOnSave/{}", id)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -698,7 +705,16 @@ impl GlobalState {
|
|||||||
this.cancel(id);
|
this.cancel(id);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?
|
})?
|
||||||
.on::<lsp_types::notification::WorkDoneProgressCancel>(|_this, _params| {
|
.on::<lsp_types::notification::WorkDoneProgressCancel>(|this, params| {
|
||||||
|
if let lsp_types::NumberOrString::String(s) = ¶ms.token {
|
||||||
|
if let Some(id) = s.strip_prefix("rust-analyzer/checkOnSave/") {
|
||||||
|
if let Ok(id) = u32::from_str_radix(id, 10) {
|
||||||
|
if let Some(flycheck) = this.flycheck.get(id as usize) {
|
||||||
|
flycheck.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Just ignore this. It is OK to continue sending progress
|
// Just ignore this. It is OK to continue sending progress
|
||||||
// notifications for this token, as the client can't know when
|
// notifications for this token, as the client can't know when
|
||||||
// we accepted notification.
|
// we accepted notification.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user