]> git.lizzy.rs Git - rust.git/commitdiff
Add command for manually running flychecks
authorLukas Wirth <lukastw97@gmail.com>
Fri, 16 Dec 2022 21:43:14 +0000 (22:43 +0100)
committerLukas Wirth <lukastw97@gmail.com>
Fri, 16 Dec 2022 21:47:19 +0000 (22:47 +0100)
crates/rust-analyzer/src/lsp_ext.rs
crates/rust-analyzer/src/main_loop.rs
docs/dev/lsp-extensions.md
editors/code/package.json
editors/code/src/commands.ts
editors/code/src/lsp_ext.ts
editors/code/src/main.ts

index a1df0b6d7dd5aae13fee85588f69ac20283c557c..a2d539cf6ca125cafa7f6a07789479ad25d877d6 100644 (file)
@@ -138,6 +138,19 @@ impl Request for CancelFlycheck {
     const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
 }
 
+pub enum RunFlycheck {}
+
+impl Notification for RunFlycheck {
+    type Params = RunFlycheckParams;
+    const METHOD: &'static str = "rust-analyzer/runFlycheck";
+}
+
+#[derive(Deserialize, Serialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct RunFlycheckParams {
+    pub text_document: Option<TextDocumentIdentifier>,
+}
+
 pub enum MatchingBrace {}
 
 impl Request for MatchingBrace {
index 274588ce0e0764f9953c09402edfca046fc02ada..d979317b21875fd4e6c5040bc923f66a3a51032d 100644 (file)
@@ -703,6 +703,88 @@ fn on_request(&mut self, req: Request) {
 
     /// Handles an incoming notification.
     fn on_notification(&mut self, not: Notification) -> Result<()> {
+        // FIXME: Move these implementations out into a module similar to on_request
+        fn run_flycheck(this: &mut GlobalState, vfs_path: VfsPath) -> bool {
+            let file_id = this.vfs.read().0.file_id(&vfs_path);
+            if let Some(file_id) = file_id {
+                let world = this.snapshot();
+                let mut updated = false;
+                let task = move || -> std::result::Result<(), ide::Cancelled> {
+                    // Trigger flychecks for all workspaces that depend on the saved file
+                    // Crates containing or depending on the saved file
+                    let crate_ids: Vec<_> = world
+                        .analysis
+                        .crates_for(file_id)?
+                        .into_iter()
+                        .flat_map(|id| world.analysis.transitive_rev_deps(id))
+                        .flatten()
+                        .sorted()
+                        .unique()
+                        .collect();
+
+                    let crate_root_paths: Vec<_> = crate_ids
+                        .iter()
+                        .filter_map(|&crate_id| {
+                            world
+                                .analysis
+                                .crate_root(crate_id)
+                                .map(|file_id| {
+                                    world
+                                        .file_id_to_file_path(file_id)
+                                        .as_path()
+                                        .map(ToOwned::to_owned)
+                                })
+                                .transpose()
+                        })
+                        .collect::<ide::Cancellable<_>>()?;
+                    let crate_root_paths: Vec<_> =
+                        crate_root_paths.iter().map(Deref::deref).collect();
+
+                    // Find all workspaces that have at least one target containing the saved file
+                    let workspace_ids =
+                        world.workspaces.iter().enumerate().filter(|(_, ws)| match ws {
+                            project_model::ProjectWorkspace::Cargo { cargo, .. } => {
+                                cargo.packages().any(|pkg| {
+                                    cargo[pkg].targets.iter().any(|&it| {
+                                        crate_root_paths.contains(&cargo[it].root.as_path())
+                                    })
+                                })
+                            }
+                            project_model::ProjectWorkspace::Json { project, .. } => project
+                                .crates()
+                                .any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c)),
+                            project_model::ProjectWorkspace::DetachedFiles { .. } => false,
+                        });
+
+                    // Find and trigger corresponding flychecks
+                    for flycheck in world.flycheck.iter() {
+                        for (id, _) in workspace_ids.clone() {
+                            if id == flycheck.id() {
+                                updated = true;
+                                flycheck.restart();
+                                continue;
+                            }
+                        }
+                    }
+                    // No specific flycheck was triggered, so let's trigger all of them.
+                    if !updated {
+                        for flycheck in world.flycheck.iter() {
+                            flycheck.restart();
+                        }
+                    }
+                    Ok(())
+                };
+                this.task_pool.handle.spawn_with_sender(move |_| {
+                    if let Err(e) = std::panic::catch_unwind(task) {
+                        tracing::error!("flycheck task panicked: {e:?}")
+                    }
+                });
+                true
+            } else {
+                false
+            }
+        }
+
         NotificationDispatcher { not: Some(not), global_state: self }
             .on::<lsp_types::notification::Cancel>(|this, params| {
                 let id: lsp_server::RequestId = match params.id {
@@ -782,6 +864,20 @@ fn on_notification(&mut self, not: Notification) -> Result<()> {
                 }
                 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) {
+                        if 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();
+                }
+                Ok(())
+            })?
             .on::<lsp_types::notification::DidSaveTextDocument>(|this, params| {
                 if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
                     // Re-fetch workspaces if a workspace related file has changed
@@ -792,82 +888,7 @@ fn on_notification(&mut self, not: Notification) -> Result<()> {
                         }
                     }
 
-                    let file_id = this.vfs.read().0.file_id(&vfs_path);
-                    if let Some(file_id) = file_id {
-                        let world = this.snapshot();
-                        let mut updated = false;
-                        let task = move || -> std::result::Result<(), ide::Cancelled> {
-                            // Trigger flychecks for all workspaces that depend on the saved file
-                            // Crates containing or depending on the saved file
-                            let crate_ids: Vec<_> = world
-                                .analysis
-                                .crates_for(file_id)?
-                                .into_iter()
-                                .flat_map(|id| world.analysis.transitive_rev_deps(id))
-                                .flatten()
-                                .sorted()
-                                .unique()
-                                .collect();
-
-                            let crate_root_paths: Vec<_> = crate_ids
-                                .iter()
-                                .filter_map(|&crate_id| {
-                                    world
-                                        .analysis
-                                        .crate_root(crate_id)
-                                        .map(|file_id| {
-                                            world
-                                                .file_id_to_file_path(file_id)
-                                                .as_path()
-                                                .map(ToOwned::to_owned)
-                                        })
-                                        .transpose()
-                                })
-                                .collect::<ide::Cancellable<_>>()?;
-                            let crate_root_paths: Vec<_> =
-                                crate_root_paths.iter().map(Deref::deref).collect();
-
-                            // Find all workspaces that have at least one target containing the saved file
-                            let workspace_ids =
-                                world.workspaces.iter().enumerate().filter(|(_, ws)| match ws {
-                                    project_model::ProjectWorkspace::Cargo { cargo, .. } => {
-                                        cargo.packages().any(|pkg| {
-                                            cargo[pkg].targets.iter().any(|&it| {
-                                                crate_root_paths.contains(&cargo[it].root.as_path())
-                                            })
-                                        })
-                                    }
-                                    project_model::ProjectWorkspace::Json { project, .. } => {
-                                        project.crates().any(|(c, _)| {
-                                            crate_ids.iter().any(|&crate_id| crate_id == c)
-                                        })
-                                    }
-                                    project_model::ProjectWorkspace::DetachedFiles { .. } => false,
-                                });
-
-                            // Find and trigger corresponding flychecks
-                            for flycheck in world.flycheck.iter() {
-                                for (id, _) in workspace_ids.clone() {
-                                    if id == flycheck.id() {
-                                        updated = true;
-                                        flycheck.restart();
-                                        continue;
-                                    }
-                                }
-                            }
-                            // No specific flycheck was triggered, so let's trigger all of them.
-                            if !updated {
-                                for flycheck in world.flycheck.iter() {
-                                    flycheck.restart();
-                                }
-                            }
-                            Ok(())
-                        };
-                        this.task_pool.handle.spawn_with_sender(move |_| {
-                            if let Err(e) = std::panic::catch_unwind(task) {
-                                tracing::error!("DidSaveTextDocument flycheck task panicked: {e:?}")
-                            }
-                        });
+                    if run_flycheck(this, vfs_path) {
                         return Ok(());
                     }
                 }
index 5aced035d52670aa46af523c4a5c9841e0463d33..308a92bebe06d931e18de3944f501144fd3ef89e 100644 (file)
@@ -1,5 +1,5 @@
 <!---
-lsp_ext.rs hash: 61fe425627f9baaa
+lsp_ext.rs hash: 1cb29d3afa36e743
 
 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:
index 5b83701a68250aefd0d8869a53f5d2f0747ef4c5..bfaad1edcea56ebdcb1427f2ffe0b6e08ee97cd5 100644 (file)
                 "command": "rust-analyzer.cancelFlycheck",
                 "title": "Cancel running flychecks",
                 "category": "rust-analyzer"
+            },
+            {
+                "command": "rust-analyzer.runFlycheck",
+                "title": "Run flycheck",
+                "category": "rust-analyzer"
             }
         ],
         "keybindings": [
index 312087e4cffef9d6c7d5e74a7590a3d2837522a1..e0b4bb63c31244afed789a62e811405cfd90cf84 100644 (file)
@@ -788,8 +788,17 @@ export function openDocs(ctx: CtxInit): Cmd {
 
 export function cancelFlycheck(ctx: CtxInit): Cmd {
     return async () => {
+        await ctx.client.sendRequest(ra.cancelFlycheck);
+    };
+}
+
+export function runFlycheck(ctx: CtxInit): Cmd {
+    return async () => {
+        const editor = ctx.activeRustEditor;
         const client = ctx.client;
-        await client.sendRequest(ra.cancelFlycheck);
+        const params = editor ? { uri: editor.document.uri.toString() } : null;
+
+        await client.sendNotification(ra.runFlycheck, { textDocument: params });
     };
 }
 
@@ -797,12 +806,12 @@ export function resolveCodeAction(ctx: CtxInit): Cmd {
     return async (params: lc.CodeAction) => {
         const client = ctx.client;
         params.command = undefined;
-        const item = await client?.sendRequest(lc.CodeActionResolveRequest.type, params);
+        const item = await client.sendRequest(lc.CodeActionResolveRequest.type, params);
         if (!item?.edit) {
             return;
         }
         const itemEdit = item.edit;
-        const edit = await client?.protocol2CodeConverter.asWorkspaceEdit(itemEdit);
+        const edit = await client.protocol2CodeConverter.asWorkspaceEdit(itemEdit);
         // filter out all text edits and recreate the WorkspaceEdit without them so we can apply
         // snippet edits on our own
         const lcFileSystemEdit = {
index 875261c48a60e4f4c22c7b35865267aa5de5f8f4..78da4e959c657bc1b810cafc572f590113d89e72 100644 (file)
@@ -81,6 +81,10 @@ export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, Te
 
 export const cancelFlycheck = new lc.RequestType0<void, void>("rust-analyzer/cancelFlycheck");
 
+export const runFlycheck = new lc.NotificationType<{
+    textDocument: lc.TextDocumentIdentifier | null;
+}>("rust-analyzer/runFlycheck");
+
 // Experimental extensions
 
 export interface SsrParams {
index 01a1a2db7fdf7c4fb187e202f29dcccd3c1def21..c5fc44b4f9f77698c0ee37eb919e5ae43a32018e 100644 (file)
@@ -150,6 +150,7 @@ function createCommands(): Record<string, CommandFactory> {
         moveItemUp: { enabled: commands.moveItemUp },
         moveItemDown: { enabled: commands.moveItemDown },
         cancelFlycheck: { enabled: commands.cancelFlycheck },
+        runFlycheck: { enabled: commands.runFlycheck },
         ssr: { enabled: commands.ssr },
         serverVersion: { enabled: commands.serverVersion },
         // Internal commands which are invoked by the server.