about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/config.rs14
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs10
-rw-r--r--crates/rust-analyzer/src/main_loop.rs27
-rw-r--r--crates/rust-analyzer/src/reload.rs10
-rw-r--r--docs/dev/lsp-extensions.md41
-rw-r--r--editors/code/package.json5
-rw-r--r--editors/code/src/commands.ts8
-rw-r--r--editors/code/src/lsp_ext.ts4
-rw-r--r--editors/code/src/main.ts1
9 files changed, 85 insertions, 35 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 6c0d712a4f4..835b37c98e2 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -1125,11 +1125,8 @@ impl Config {
         }
     }
 
-    pub fn flycheck(&self) -> Option<FlycheckConfig> {
-        if !self.data.checkOnSave_enable {
-            return None;
-        }
-        let flycheck_config = match &self.data.checkOnSave_overrideCommand {
+    pub fn flycheck(&self) -> FlycheckConfig {
+        match &self.data.checkOnSave_overrideCommand {
             Some(args) if !args.is_empty() => {
                 let mut args = args.clone();
                 let command = args.remove(0);
@@ -1183,8 +1180,11 @@ impl Config {
                 extra_args: self.data.checkOnSave_extraArgs.clone(),
                 extra_env: self.check_on_save_extra_env(),
             },
-        };
-        Some(flycheck_config)
+        }
+    }
+
+    pub fn check_on_save(&self) -> bool {
+        self.data.checkOnSave_enable
     }
 
     pub fn runnables(&self) -> RunnablesConfig {
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index a2d539cf6ca..65620b4209b 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -132,9 +132,8 @@ pub struct ExpandedMacro {
 
 pub enum CancelFlycheck {}
 
-impl Request for CancelFlycheck {
+impl Notification for CancelFlycheck {
     type Params = ();
-    type Result = ();
     const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
 }
 
@@ -145,6 +144,13 @@ impl Notification for RunFlycheck {
     const METHOD: &'static str = "rust-analyzer/runFlycheck";
 }
 
+pub enum ClearFlycheck {}
+
+impl Notification for ClearFlycheck {
+    type Params = ();
+    const METHOD: &'static str = "rust-analyzer/clearFlycheck";
+}
+
 #[derive(Deserialize, Serialize, Debug)]
 #[serde(rename_all = "camelCase")]
 pub struct RunFlycheckParams {
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index d979317b218..47776f734b0 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -581,10 +581,7 @@ impl GlobalState {
                 // When we're running multiple flychecks, we have to include a disambiguator in
                 // the title, or the editor complains. Note that this is a user-facing string.
                 let title = if self.flycheck.len() == 1 {
-                    match self.config.flycheck() {
-                        Some(config) => format!("{}", config),
-                        None => "cargo check".to_string(),
-                    }
+                    format!("{}", self.config.flycheck())
                 } else {
                     format!("cargo check (#{})", id + 1)
                 };
@@ -593,7 +590,7 @@ impl GlobalState {
                     state,
                     message,
                     None,
-                    Some(format!("rust-analyzer/checkOnSave/{}", id)),
+                    Some(format!("rust-analyzer/flycheck/{}", id)),
                 );
             }
         }
@@ -638,7 +635,6 @@ 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)
@@ -796,7 +792,7 @@ impl GlobalState {
             })?
             .on::<lsp_types::notification::WorkDoneProgressCancel>(|this, params| {
                 if let lsp_types::NumberOrString::String(s) = &params.token {
-                    if let Some(id) = s.strip_prefix("rust-analyzer/checkOnSave/") {
+                    if let Some(id) = s.strip_prefix("rust-analyzer/flycheck/") {
                         if let Ok(id) = u32::from_str_radix(id, 10) {
                             if let Some(flycheck) = this.flycheck.get(id as usize) {
                                 flycheck.cancel();
@@ -825,6 +821,7 @@ impl GlobalState {
                 }
                 Ok(())
             })?
+            .on::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)?
             .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| {
                 if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) {
                     match this.mem_docs.get_mut(&path) {
@@ -864,6 +861,10 @@ impl GlobalState {
                 }
                 Ok(())
             })?
+            .on::<lsp_ext::ClearFlycheck>(|this, ()| {
+                this.diagnostics.clear_check_all();
+                Ok(())
+            })?
             .on::<lsp_ext::RunFlycheck>(|this, params| {
                 if let Some(text_document) = params.text_document {
                     if let Ok(vfs_path) = from_proto::vfs_path(&text_document.uri) {
@@ -888,14 +889,14 @@ impl GlobalState {
                         }
                     }
 
-                    if run_flycheck(this, vfs_path) {
+                    if !this.config.check_on_save() || run_flycheck(this, vfs_path) {
                         return Ok(());
                     }
-                }
-
-                // No specific flycheck was triggered, so let's trigger all of them.
-                for flycheck in this.flycheck.iter() {
-                    flycheck.restart();
+                } else if this.config.check_on_save() {
+                    // No specific flycheck was triggered, so let's trigger all of them.
+                    for flycheck in this.flycheck.iter() {
+                        flycheck.restart();
+                    }
                 }
                 Ok(())
             })?
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 748a189c203..3e7664d7d3e 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -449,15 +449,7 @@ impl GlobalState {
 
     fn reload_flycheck(&mut self) {
         let _p = profile::span("GlobalState::reload_flycheck");
-        let config = match self.config.flycheck() {
-            Some(it) => it,
-            None => {
-                self.flycheck = Arc::new([]);
-                self.diagnostics.clear_check_all();
-                return;
-            }
-        };
-
+        let config = self.config.flycheck();
         let sender = self.flycheck_sender.clone();
         let invocation_strategy = match config {
             FlycheckConfig::CargoCommand { .. } => flycheck::InvocationStrategy::PerWorkspace,
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 308a92bebe0..1bbb4c2323c 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp_ext.rs hash: 1cb29d3afa36e743
+lsp_ext.rs hash: 45bd7985265725c5
 
 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:
@@ -459,6 +459,45 @@ Note that this functionality is intended primarily to inform the end user about
 In particular, it's valid for the client to completely ignore this extension.
 Clients are discouraged from but are allowed to use the `health` status to decide if it's worth sending a request to the server.
 
+### Controlling Flycheck
+
+The flycheck/checkOnSave feature can be controlled via notifications sent by the client to the server.
+
+**Method:** `rust-analyzer/runFlycheck`
+
+**Notification:**
+
+```typescript
+interface RunFlycheckParams {
+    /// The text document whose cargo workspace flycheck process should be started.
+    /// If the document is null or does not belong to a cargo workspace all flycheck processes will be started.
+    textDocument: lc.TextDocumentIdentifier | null;
+}
+```
+
+Triggers the flycheck processes.
+
+
+**Method:** `rust-analyzer/clearFlycheck`
+
+**Notification:**
+
+```typescript
+interface ClearFlycheckParams {}
+```
+
+Clears the flycheck diagnostics.
+
+**Method:** `rust-analyzer/cancelFlycheck`
+
+**Notification:**
+
+```typescript
+interface CancelFlycheckParams {}
+```
+
+Cancels all running flycheck processes.
+
 ## Syntax Tree
 
 **Method:** `rust-analyzer/syntaxTree`
diff --git a/editors/code/package.json b/editors/code/package.json
index bfaad1edcea..f9b0e28dadb 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -251,6 +251,11 @@
                 "command": "rust-analyzer.runFlycheck",
                 "title": "Run flycheck",
                 "category": "rust-analyzer"
+            },
+            {
+                "command": "rust-analyzer.clearFlycheck",
+                "title": "Clear flycheck diagnostics",
+                "category": "rust-analyzer"
             }
         ],
         "keybindings": [
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index e0b4bb63c31..cb4e13e2c60 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -788,7 +788,13 @@ export function openDocs(ctx: CtxInit): Cmd {
 
 export function cancelFlycheck(ctx: CtxInit): Cmd {
     return async () => {
-        await ctx.client.sendRequest(ra.cancelFlycheck);
+        await ctx.client.sendNotification(ra.cancelFlycheck);
+    };
+}
+
+export function clearFlycheck(ctx: CtxInit): Cmd {
+    return async () => {
+        await ctx.client.sendNotification(ra.clearFlycheck);
     };
 }
 
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index 78da4e959c6..29349cc20f5 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -79,8 +79,8 @@ export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, Te
     "rust-analyzer/relatedTests"
 );
 
-export const cancelFlycheck = new lc.RequestType0<void, void>("rust-analyzer/cancelFlycheck");
-
+export const cancelFlycheck = new lc.NotificationType0("rust-analyzer/cancelFlycheck");
+export const clearFlycheck = new lc.NotificationType0("rust-analyzer/clearFlycheck");
 export const runFlycheck = new lc.NotificationType<{
     textDocument: lc.TextDocumentIdentifier | null;
 }>("rust-analyzer/runFlycheck");
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index c5fc44b4f9f..9a9667b2cd2 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -150,6 +150,7 @@ function createCommands(): Record<string, CommandFactory> {
         moveItemUp: { enabled: commands.moveItemUp },
         moveItemDown: { enabled: commands.moveItemDown },
         cancelFlycheck: { enabled: commands.cancelFlycheck },
+        clearFlycheck: { enabled: commands.clearFlycheck },
         runFlycheck: { enabled: commands.runFlycheck },
         ssr: { enabled: commands.ssr },
         serverVersion: { enabled: commands.serverVersion },