Skip to content

Commit 106285b

Browse files
committed
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 #6895 ![Code_VbXgP3SbFD](https://user-images.githubusercontent.com/3757771/196205329-2df93451-c143-4d1b-a700-d988edf55efa.gif)
2 parents 067c410 + e41023c commit 106285b

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

crates/rust-analyzer/src/lsp_utils.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ impl GlobalState {
8787
state: Progress,
8888
message: Option<String>,
8989
fraction: Option<f64>,
90+
cancel_token: Option<String>,
9091
) {
9192
if !self.config.work_done_progress() {
9293
return;
@@ -95,7 +96,10 @@ impl GlobalState {
9596
assert!((0.0..=1.0).contains(&f));
9697
(f * 100.0) as u32
9798
});
98-
let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title));
99+
let cancellable = Some(cancel_token.is_some());
100+
let token = lsp_types::ProgressToken::String(
101+
cancel_token.unwrap_or_else(|| format!("rustAnalyzer/{}", title)),
102+
);
99103
let work_done_progress = match state {
100104
Progress::Begin => {
101105
self.send_request::<lsp_types::request::WorkDoneProgressCreate>(
@@ -105,14 +109,14 @@ impl GlobalState {
105109

106110
lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
107111
title: title.into(),
108-
cancellable: None,
112+
cancellable,
109113
message,
110114
percentage,
111115
})
112116
}
113117
Progress::Report => {
114118
lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
115-
cancellable: None,
119+
cancellable,
116120
message,
117121
percentage,
118122
})

crates/rust-analyzer/src/main_loop.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ impl GlobalState {
257257
}
258258
};
259259

260-
self.report_progress("Indexing", state, message, Some(fraction));
260+
self.report_progress("Indexing", state, message, Some(fraction), None);
261261
}
262262
}
263263
Event::Vfs(message) => {
@@ -465,7 +465,7 @@ impl GlobalState {
465465
}
466466
};
467467

468-
self.report_progress("Fetching", state, msg, None);
468+
self.report_progress("Fetching", state, msg, None, None);
469469
}
470470
Task::FetchBuildData(progress) => {
471471
let (state, msg) = match progress {
@@ -481,7 +481,7 @@ impl GlobalState {
481481
};
482482

483483
if let Some(state) = state {
484-
self.report_progress("Loading", state, msg, None);
484+
self.report_progress("Loading", state, msg, None, None);
485485
}
486486
}
487487
}
@@ -518,6 +518,7 @@ impl GlobalState {
518518
state,
519519
Some(format!("{}/{}", n_done, n_total)),
520520
Some(Progress::fraction(n_done, n_total)),
521+
None,
521522
)
522523
}
523524
}
@@ -584,7 +585,13 @@ impl GlobalState {
584585
} else {
585586
format!("cargo check (#{})", id + 1)
586587
};
587-
self.report_progress(&title, state, message, None);
588+
self.report_progress(
589+
&title,
590+
state,
591+
message,
592+
None,
593+
Some(format!("rust-analyzer/checkOnSave/{}", id)),
594+
);
588595
}
589596
}
590597
}
@@ -698,7 +705,16 @@ impl GlobalState {
698705
this.cancel(id);
699706
Ok(())
700707
})?
701-
.on::<lsp_types::notification::WorkDoneProgressCancel>(|_this, _params| {
708+
.on::<lsp_types::notification::WorkDoneProgressCancel>(|this, params| {
709+
if let lsp_types::NumberOrString::String(s) = &params.token {
710+
if let Some(id) = s.strip_prefix("rust-analyzer/checkOnSave/") {
711+
if let Ok(id) = u32::from_str_radix(id, 10) {
712+
if let Some(flycheck) = this.flycheck.get(id as usize) {
713+
flycheck.cancel();
714+
}
715+
}
716+
}
717+
}
702718
// Just ignore this. It is OK to continue sending progress
703719
// notifications for this token, as the client can't know when
704720
// we accepted notification.

0 commit comments

Comments
 (0)