Awesome
Cargo Runner
Open VSX | Vscode Marketplace
</br> </br>
A Complementary Tool to rust-analyzer to streamline your Rust development and enhance your productivity.
No unicorns or crabs were harmed during the creation of this tool.
Requirements
- rust-analyzer
- codelldb
NOTE: If these are missing, the extension will not load.
Features
-
Command Runner - press <kbd>CMD</kbd>+<kbd>R</kbd> to run any command on your current cursor position.
-
Override Rust Analyzer Config - press <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>R</kbd> to override any command on
workspace level
by providing cargo args , test binary args, ENV, features.
For more info read rules
-
Codelldb Debugger Integration - add breakpoints to debug your code.
-
Rust Analyzer Integration - share rust-analyzer built-in configuration.
-
Cargo Nextest Integration - Enable / Disable
cargo-nextest
from vscode settings -
Override $CARGO_HOME from vscode settings (used by
cargo-nextest
)
Use cases
Run
- Run Main
- Go to your
main.rs
file and press <kbd>CMD</kbd>+<kbd>R</kbd>
- Other Binaries
- Go to any
src/bin/*.rs
file or to any files declared as[[bin]]
inCargo.toml
and press <kbd>CMD</kbd>+<kbd>R</kbd>
- Examples
- Go to any
examples/*.rs
file and press <kbd>CMD</kbd>+<kbd>R</kbd>
NOTE: main() fn would be the fallback scope on any file , if main() fn exists on that file, considering it as the parent module to run cargo commands on.
Even if your are in main.rs and you don't have main() fn , it will not execute any cargo commands in that file.
Test
- Create a test
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
fn it_works_too() {
assert_eq!(2 + 2, 4);
}
}
NOTE: The scope varies , if your cursor is on a scope outside any fn test , it will go up to its parent module and run all the tests in that module.
To Enable
cargo-nextest
setcargoRunner.enableNextest
totrue
in yoursettings.json
- Press <kbd>CMD</kbd>+<kbd>R</kbd> on any code block you want to run tests on
Doc test
WARNING: Doc test only works with a crate-type of lib
- Add doc-test on a function e.g.
lib.rs
///
/// ```rust
/// use common::add;
/// assert_eq!(add(1, 2), 3);
/// ```
pub fn add(left: usize, right: usize) -> usize {
left + right
}
doc-test works on any function or method, Struct , Enum and Union that has doc-block and code block of
rust
NOTE: The scope varies , if you put your cursor on the Struct definition and that Struct has many doc-test on its impl block then it will run all of them. Same goes for Enum and Union .
- Press <kbd>CMD</kbd>+<kbd>R</kbd> to run
doc-tests
Debugging
- Add breakpoint on a rust file e.g.
main.rs
or any other rust file
fn main() {
println!("Hello, world!"); // add break point here
}
- Press <kbd>CMD</kbd>+<kbd>R</kbd> to debug the program
Note: This would only work if codelldb
is installed.
REMINDER: You cannot debug any benchmarks or doc-tests , when you try to debug benches it would just run the cargo bench
Bench
- set version of rust to
nightly
inrust-toolchain.toml
using our Override Command
Do the Following:
-
press <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>R</kbd> to override rust-analyzer config
-
type:
+nightly
-
it would be saved on your
rust-toolchain.toml
as follows
[toolchain]
channel = "nightly"
- Add to the root of the module (e.g.
main.rs
)
Root module means
#![feature(test)]
extern crate test;
- create a new bench fn
#[cfg(test)]
mod tests {
use std::time::Duration;
use test::Bencher;
use tokio::{runtime::Runtime, time::sleep};
#[bench]
fn bench_async_example(b: &mut Bencher) {
let runtime = Runtime::new().unwrap();
b.iter(|| {
runtime.block_on(async {
sleep(Duration::from_millis(5000)).await;
let x: u32 = (1..100).sum();
x
});
});
}
}
FEATURE Supports
cargo-nextest
to run benchmarks
Override Config
Rules:
Rule 1: You can either add or remove configurations, but not both at the same time.
Rule 2: You can combine one or more keywords when adding or removing configurations.
Rule 3: Order does not matter when typing keywords to add or remove configurations. However, when marking the start of test binary arguments with --, everything typed afterward will be saved as test binary arguments.
Rule 4: Removing configurations is marked with !
for more info head to Removing Configuration
Usage:
-
Press <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>R</kbd> or bind it to a key you like.
-
type the params , env, features, cargo-target, target, test binary args you want to add or remove.
Adding configuration
- Adding Cargo Arguments
type: e.g. --release --profile=default
It would be saved on your settings.json
as follows
"rust-analyzer.runnables.extraArgs": [
"--release",
"profile=default"
],
Example command output:
cargo run --package codec --bin codec --release --profile=default
</details>
- Adding Test Binary Args
IMPORTANT: The --
should be added to mark the start of adding test binary args.
type: e.g. -- --quiet --show-output --color=always --nocapture
It would be saved on your settings.json
as follows
"rust-analyzer.runnables.extraTestBinaryArgs": [
"--quiet",
"--show-output",
"--color=always",
"--nocapture",
],
This would be used for both cargo test
and cargo-nextest
when generating the command to run.
example command output:
cargo test --package codec --bin codec -- tests::it_works --exact --quiet --show-output --color=always --nocapture
</details>
</br>
</br>NOTE: To check the allowed args for
cargo test
run cargo test -- --help in your terminal.
</br>NOTE To check the allowed args for
cargo-nextest
run cargo nextest run --help in your terminal.
- Adding ENV vars
type e.g. RUST_BACKTRACE=full RUST_LOG=debug
it would be saved on your settings.json
as follows
"rust-analyzer.runnables.extraEnv": {
"RUST_BACKTRACE": "full",
"RUST_LOG": "debug"
}
</details>
For more info check Setting up runnables environment variables
- Adding Features
Resolver version 2 command-line flags
type e.g. --features=example,default --no-default-features
it would be saved on your settings.json
as follows
"rust-analyzer.cargo.noDefaultFeatures": true,
"rust-analyzer.cargo.features": [
"example",
"default"
],
example command output:
cargo run --package codec --bin codec --features example --features default --no-default-features
</details>
NOTE : This is not recommended for workspaces setup as any features define here would also be applied to all crates in the workspace.
For better control over features , check Bonus section.
- Adding target
A. Add --cargo-target
If you want to enable target specific features, you have to add the target to the cargo target.
type e.g. --cargo-target=wasm32-unknown-unknown
It would be saved on your settings.json
as follows
{
"rust-analyzer.cargo.target": "wasm32-unknown-unknown",
}
</details>
Note: To check if this has any effect on your code.
We need to compare the code with the following example:
#[cfg(target_arch = "wasm32")]
fn main() {
println!("Hello, world!");
}
This code is active
#[cfg(not(target_arch = "wasm32"))]
fn main() {
println!("Hello, world!");
}
while on 2nd example code is inactive
B. Add --target
type e.g. --target=wasm32-unknown-unknown
It would be saved on your settings.json
as follows
"rust-analyzer.runnables.extraArgs": [
"--target=wasm32-unknown-unknown",
],
</details>
A. Add --target-dir
This prevents rust-analyzer's cargo check and initial build-script and proc-macro building from locking the Cargo.lock at the expense of duplicating build artifacts.
Set to true to use a subdirectory of the existing target directory or set to a path relative to the workspace to use that path.
type: e.g. --target-dir=true
or --target-dir=false
or --target-dir
It would be saved on your settings.json
as follows
"rust-analyzer.cargo.targetDir": true,
</details>
</br>
- Add rust channel to
rust-toolchain.toml
type: +nightly
or any valid rust channel format e.g. +1.83.0
, +nightly-2023-08-01
, +stable-x86_64-pc-windows-msvc
IMPORTANT: append +
to the channel name.
[toolchain]
channel = "nightly"
</details>
</br>
This prevents rust-analyzer's cargo check and initial build-script and proc-macro building from locking the Cargo.lock at the expense of duplicating build artifacts.
Removing Configuration
-
Remove Extra Args : type
!args
or just!
for shortcut -
Removing Test Binary Args : type
!--
-
Removing ENV vars : type
!env
TODO: granular control on env vars with rust-analyzer.runnables.extraEnv
see: Setting up runnables environment variables
-
Removing Features : type
!features
-
Removing Cargo Target : type
!target
-
Removing Cargo Target Dir: type
!targetDir
Note: to remove --target
just use the default !
or !args
Configuration Files
Note: This is not part of the plugin but is a Cargo-related feature that helps manage your workspace.
<details> <summary> 1. Cargo.toml </summary>Adding Features
This is only relevant for the [[bin]], [[bench]], [[test]], and [[example]] sections, it has no effect on [lib].
[lib]
name = "foo" # The name of the target.
path = "src/lib.rs" # The source file of the target.
test = true # Is tested by default.
doctest = true # Documentation examples are tested by default.
bench = true # Is benchmarked by default.
doc = true # Is documented by default.
proc-macro = false # Set to `true` for a proc-macro library.
harness = true # Use libtest harness.
edition = "2015" # The edition of the target.
crate-type = ["lib"] # The crate types to generate.
required-features = [] # Features required to build this target (N/A for lib).
Note: The list of targets can be configured in the Cargo.toml manifest, often inferred automatically by the directory layout of the source files.
This is the default directory layout for any cargo project.
.
├── Cargo.lock
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── main.rs
│ └── bin/
│ ├── named-executable.rs
│ ├── another-executable.rs
│ └── multi-file-executable/
│ ├── main.rs
│ └── some_module.rs
├── benches/
│ ├── large-input.rs
│ └── multi-file-bench/
│ ├── main.rs
│ └── bench_module.rs
├── examples/
│ ├── simple.rs
│ └── multi-file-example/
│ ├── main.rs
│ └── ex_module.rs
└── tests/
├── some-integration-tests.rs
└── multi-file-test/
├── main.rs
└── test_module.rs
Note: This would only work if you already defined your features on Cargo.toml
Example:
Cargo.toml
[[bin]]
name = "codec"
path = "src/main.rs"
required-features = ["example"]
[features]
default = ["example"]
example = []
The required-features field allows fine-grained control over specific binaries or libraries, unlike overriding rust-analyzer.cargo.features, which applies on workspace level.
path field can be inferred from the directory layout of the source files.
The path field specifies where the source for the crate is located, relative to the Cargo.toml file.
If not specified, the inferred path is used based on the target name.
For other more info about Cargo Manifest Format check Cargo Manifest Format
</details>- Usage of
.cargo/config.toml
For more info on how to configure manually .cargo/config
check Config file
- Toolchain
For more info on how to configure manually check Toolchain File
- Cargo Workspace (Cargo.toml)
For more info on how to configure manually check Cargo Workspace
Issues
If you find any issues please open an issue on the github repo.
Note: You can set the Cargo Runner: Log Level
to debug on vscode settings to get more info on what is happening.
License
Changelog
Support me
If you think I help you in anyway, and want to help me keep doing what I love, the best way to say thank you is to sponsor me on GitHub.