'How do I automatically run "cargo fix" on save in VSCode?

  • Currently, I use VSCode as my IDE when programming Rust.
  • I use the rust-analyzer VSCode extension, since it seems to be the best one out there for Rust (as of 2022).

I have the following two entries in my "settings.json" for VSCode:

{
  "rust-analyzer.checkOnSave.command": "clippy",

  "[rust]": {
    "editor.formatOnSave": true,
  },
}
  • This makes it so that clippy (the linter) runs automatically upon pressing Ctrl + s to save the file.
  • It also makes it so that rustfmt (the formatter) runs automatically upon pressing Ctrl + s to save the file.

In addition to these two things, I also want cargo fix to run automatically upon pressing Ctrl + s to save the file, because doing that automatically cleans up unused imports.

How can I accomplish this?

(I want unused imports to be automatically cleaned up for the same reason that I want an automatic formatter. Manually removing unused imports is tedium and a complete waste of my time in the same way that manually adding the appropriate amount of tabs or spaces is.)



Solution 1:[1]

Clippy has a --fix option, that applies the suggested fixes automatically. So all you need is to change the the on-save check command. However, you need two arguments clippy and --fix, and for that you cannot use rust-analyzer.checkOnSave.command and have to override the full command:

{
  "rust-analyzer.checkOnSave.overrideCommand": [
    "cargo",
    "clippy",
    "--fix",
    "--workspace",
    "--message-format=json",
    "--all-targets",
    "--allow-dirty"
  ],
}

Beware, however, that it will apply all automatically-applicable suggestions, not just remove unused imports.

All of these flags are what rust-analyzer automatically adds to rust-analyzer.checkOnSave.command, but when you use rust-analyzer.checkOnSave.overrideCommand you have to specify them yourself. Here's a short description of them (the docs has more details):

  • --workspace - apply the command to all members in the Cargo workspace, and not just one package.
  • --message-format=json - emit JSON as a response instead of human-readable output, so that rust-analyzer can analyze the response and show the errors.
  • --all-targets - check all things, i.e. binaries, libraries, examples, tests and benchmarks.
  • --allow-dirty - fix even if workspace has changes.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1