Implement lsp extension for cancelling running flychecks

This commit is contained in:
Lukas Wirth 2022-08-19 08:52:31 +02:00
parent 917bd68b37
commit 45b7b6a60a
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.
pub fn update(&self) {
self.sender.send(Restart).unwrap();
pub fn restart(&self) {
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 {
@ -122,7 +127,10 @@ pub enum Progress {
DidCancel,
}
struct Restart;
enum Restart {
Yes,
No,
}
struct FlycheckActor {
id: usize,
@ -149,6 +157,7 @@ impl FlycheckActor {
config: FlycheckConfig,
workspace_root: AbsPathBuf,
) -> FlycheckActor {
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
}
fn progress(&self, progress: Progress) {
@ -164,10 +173,13 @@ impl FlycheckActor {
fn run(mut self, inbox: Receiver<Restart>) {
while let Some(event) = self.next_event(&inbox) {
match event {
Event::Restart(Restart) => {
Event::Restart(Restart::No) => {
self.cancel_check_process();
}
Event::Restart(Restart::Yes) => {
// Cancel the previously spawned 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();
tracing::debug!(?command, "will restart flycheck");
@ -223,6 +235,10 @@ impl FlycheckActor {
fn cancel_check_process(&mut self) {
if let Some(cargo_handle) = self.cargo_handle.take() {
tracing::debug!(
command = ?self.check_command(),
"did cancel flycheck"
);
cargo_handle.cancel();
self.progress(Progress::DidCancel);
}

View file

@ -51,6 +51,12 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
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(
snap: GlobalStateSnapshot,
params: lsp_ext::AnalyzerStatusParams,

View file

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

View file

@ -288,7 +288,7 @@ impl GlobalState {
if became_quiescent {
// 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() {
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::MemoryUsage>(handlers::handle_memory_usage)
.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::OnEnter>(handlers::handle_on_enter)
.on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
@ -779,7 +780,7 @@ impl GlobalState {
for (id, _) in workspace_ids.clone() {
if id == flycheck.id() {
updated = true;
flycheck.update();
flycheck.restart();
continue;
}
}
@ -798,7 +799,7 @@ impl GlobalState {
// No specific flycheck was triggered, so let's trigger all of them.
if !updated {
for flycheck in &this.flycheck {
flycheck.update();
flycheck.restart();
}
}
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
need to adjust this doc as well and ping this issue:

View file

@ -235,6 +235,11 @@
"command": "rust-analyzer.moveItemDown",
"title": "Move item down",
"category": "rust-analyzer"
},
{
"command": "rust-analyzer.cancelFlycheck",
"title": "Cancel running flychecks",
"category": "rust-analyzer"
}
],
"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 {
const client = ctx.client;
return async (params: lc.CodeAction) => {

View file

@ -75,6 +75,23 @@ export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro |
"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 {
textDocument: lc.TextDocumentIdentifier;
positions: lc.Position[];
@ -127,19 +144,6 @@ export interface TestInfo {
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 {
/**
* 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("moveItemUp", commands.moveItemUp);
ctx.registerCommand("moveItemDown", commands.moveItemDown);
ctx.registerCommand("cancelFlycheck", commands.cancelFlycheck);
defaultOnEnter.dispose();
ctx.registerCommand("onEnter", commands.onEnter);