Auto merge of #13063 - Veykril:stop-flycheck, r=Veykril

Implement lsp extension for cancelling running flychecks

Fixes https://github.com/rust-lang/rust-analyzer/issues/4828
This commit is contained in:
bors 2022-08-19 06:58:52 +00:00
commit 04c487dd51
9 changed files with 69 additions and 22 deletions

View file

@ -77,8 +77,13 @@ impl FlycheckHandle {
} }
/// Schedule a re-start of the cargo check worker. /// Schedule a re-start of the cargo check worker.
pub fn update(&self) { pub fn restart(&self) {
self.sender.send(Restart).unwrap(); self.sender.send(Restart::Yes).unwrap();
}
/// Stop this cargo check worker.
pub fn cancel(&self) {
self.sender.send(Restart::No).unwrap();
} }
pub fn id(&self) -> usize { pub fn id(&self) -> usize {
@ -122,7 +127,10 @@ pub enum Progress {
DidCancel, DidCancel,
} }
struct Restart; enum Restart {
Yes,
No,
}
struct FlycheckActor { struct FlycheckActor {
id: usize, id: usize,
@ -149,6 +157,7 @@ impl FlycheckActor {
config: FlycheckConfig, config: FlycheckConfig,
workspace_root: AbsPathBuf, workspace_root: AbsPathBuf,
) -> FlycheckActor { ) -> FlycheckActor {
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None } FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
} }
fn progress(&self, progress: Progress) { fn progress(&self, progress: Progress) {
@ -164,10 +173,13 @@ impl FlycheckActor {
fn run(mut self, inbox: Receiver<Restart>) { fn run(mut self, inbox: Receiver<Restart>) {
while let Some(event) = self.next_event(&inbox) { while let Some(event) = self.next_event(&inbox) {
match event { match event {
Event::Restart(Restart) => { Event::Restart(Restart::No) => {
self.cancel_check_process();
}
Event::Restart(Restart::Yes) => {
// Cancel the previously spawned process // Cancel the previously spawned process
self.cancel_check_process(); self.cancel_check_process();
while let Ok(Restart) = inbox.recv_timeout(Duration::from_millis(50)) {} while let Ok(_) = inbox.recv_timeout(Duration::from_millis(50)) {}
let command = self.check_command(); let command = self.check_command();
tracing::debug!(?command, "will restart flycheck"); tracing::debug!(?command, "will restart flycheck");
@ -223,6 +235,10 @@ impl FlycheckActor {
fn cancel_check_process(&mut self) { fn cancel_check_process(&mut self) {
if let Some(cargo_handle) = self.cargo_handle.take() { if let Some(cargo_handle) = self.cargo_handle.take() {
tracing::debug!(
command = ?self.check_command(),
"did cancel flycheck"
);
cargo_handle.cancel(); cargo_handle.cancel();
self.progress(Progress::DidCancel); self.progress(Progress::DidCancel);
} }

View file

@ -51,6 +51,12 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
Ok(()) Ok(())
} }
pub(crate) fn handle_cancel_flycheck(state: &mut GlobalState, _: ()) -> Result<()> {
let _p = profile::span("handle_stop_flycheck");
state.flycheck.iter().for_each(|flycheck| flycheck.cancel());
Ok(())
}
pub(crate) fn handle_analyzer_status( pub(crate) fn handle_analyzer_status(
snap: GlobalStateSnapshot, snap: GlobalStateSnapshot,
params: lsp_ext::AnalyzerStatusParams, params: lsp_ext::AnalyzerStatusParams,

View file

@ -129,6 +129,14 @@ pub struct ExpandedMacro {
pub expansion: String, pub expansion: String,
} }
pub enum CancelFlycheck {}
impl Request for CancelFlycheck {
type Params = ();
type Result = ();
const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
}
pub enum MatchingBrace {} pub enum MatchingBrace {}
impl Request for MatchingBrace { impl Request for MatchingBrace {

View file

@ -288,7 +288,7 @@ impl GlobalState {
if became_quiescent { if became_quiescent {
// Project has loaded properly, kick off initial flycheck // Project has loaded properly, kick off initial flycheck
self.flycheck.iter().for_each(FlycheckHandle::update); self.flycheck.iter().for_each(FlycheckHandle::restart);
if self.config.prefill_caches() { if self.config.prefill_caches() {
self.prime_caches_queue.request_op("became quiescent".to_string()); self.prime_caches_queue.request_op("became quiescent".to_string());
} }
@ -590,6 +590,7 @@ impl GlobalState {
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload) .on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage) .on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph) .on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
.on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines) .on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
.on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter) .on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
.on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range) .on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
@ -779,7 +780,7 @@ impl GlobalState {
for (id, _) in workspace_ids.clone() { for (id, _) in workspace_ids.clone() {
if id == flycheck.id() { if id == flycheck.id() {
updated = true; updated = true;
flycheck.update(); flycheck.restart();
continue; continue;
} }
} }
@ -798,7 +799,7 @@ impl GlobalState {
// No specific flycheck was triggered, so let's trigger all of them. // No specific flycheck was triggered, so let's trigger all of them.
if !updated { if !updated {
for flycheck in &this.flycheck { for flycheck in &this.flycheck {
flycheck.update(); flycheck.restart();
} }
} }
Ok(()) Ok(())

View file

@ -1,5 +1,5 @@
<!--- <!---
lsp_ext.rs hash: 2a188defec26cc7c lsp_ext.rs hash: 7b710095d773b978
If you need to change the above hash to make the test pass, please check if you If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue: need to adjust this doc as well and ping this issue:

View file

@ -235,6 +235,11 @@
"command": "rust-analyzer.moveItemDown", "command": "rust-analyzer.moveItemDown",
"title": "Move item down", "title": "Move item down",
"category": "rust-analyzer" "category": "rust-analyzer"
},
{
"command": "rust-analyzer.cancelFlycheck",
"title": "Cancel running flychecks",
"category": "rust-analyzer"
} }
], ],
"keybindings": [ "keybindings": [

View file

@ -817,6 +817,12 @@ export function openDocs(ctx: Ctx): Cmd {
}; };
} }
export function cancelFlycheck(ctx: Ctx): Cmd {
return async () => {
await ctx.client.sendRequest(ra.cancelFlycheck);
};
}
export function resolveCodeAction(ctx: Ctx): Cmd { export function resolveCodeAction(ctx: Ctx): Cmd {
const client = ctx.client; const client = ctx.client;
return async (params: lc.CodeAction) => { return async (params: lc.CodeAction) => {

View file

@ -75,6 +75,23 @@ export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro |
"rust-analyzer/expandMacro" "rust-analyzer/expandMacro"
); );
export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
"rust-analyzer/relatedTests"
);
export const cancelFlycheck = new lc.RequestType0<void, void>("rust-analyzer/cancelFlycheck");
// Experimental extensions
export interface SsrParams {
query: string;
parseOnly: boolean;
textDocument: lc.TextDocumentIdentifier;
position: lc.Position;
selections: readonly lc.Range[];
}
export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
export interface MatchingBraceParams { export interface MatchingBraceParams {
textDocument: lc.TextDocumentIdentifier; textDocument: lc.TextDocumentIdentifier;
positions: lc.Position[]; positions: lc.Position[];
@ -127,19 +144,6 @@ export interface TestInfo {
runnable: Runnable; runnable: Runnable;
} }
export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
"rust-analyzer/relatedTests"
);
export interface SsrParams {
query: string;
parseOnly: boolean;
textDocument: lc.TextDocumentIdentifier;
position: lc.Position;
selections: readonly lc.Range[];
}
export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
export interface CommandLink extends lc.Command { export interface CommandLink extends lc.Command {
/** /**
* A tooltip for the command, when represented in the UI. * A tooltip for the command, when represented in the UI.

View file

@ -163,6 +163,7 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
ctx.registerCommand("peekTests", commands.peekTests); ctx.registerCommand("peekTests", commands.peekTests);
ctx.registerCommand("moveItemUp", commands.moveItemUp); ctx.registerCommand("moveItemUp", commands.moveItemUp);
ctx.registerCommand("moveItemDown", commands.moveItemDown); ctx.registerCommand("moveItemDown", commands.moveItemDown);
ctx.registerCommand("cancelFlycheck", commands.cancelFlycheck);
defaultOnEnter.dispose(); defaultOnEnter.dispose();
ctx.registerCommand("onEnter", commands.onEnter); ctx.registerCommand("onEnter", commands.onEnter);