rust-analyzer/docs/user/assists.md
Wesley Norris cbc6f94573 Add add_new assist
Adds a new assist to autogenerate a new fn based on the selected struct,
excluding tuple structs and unions. The fn will inherit the same
visibility as the struct and the assist will attempt to reuse any
existing impl blocks that exist at the same level of struct.
2019-11-09 10:56:36 -05:00

6.8 KiB

Assists

Cursor position or selection is signified by character.

add_derive

Adds a new #[derive()] clause to a struct or enum.

// BEFORE
struct Point {
    x: u32,
    y: u32,
}

// AFTER
#[derive()]
struct Point {
    x: u32,
    y: u32,
}

add_explicit_type

Specify type for a let binding.

// BEFORE
fn main() {
    let x = 92;
}

// AFTER
fn main() {
    let x: i32 = 92;
}

add_hash

Adds a hash to a raw string literal.

// BEFORE
fn main() {
    r#"Hello,┃ World!"#;
}

// AFTER
fn main() {
    r##"Hello, World!"##;
}

add_impl

Adds a new inherent impl for a type.

// BEFORE
struct Ctx<T: Clone> {
     data: T,
}

// AFTER
struct Ctx<T: Clone> {
     data: T,
}

impl<T: Clone> Ctx<T> {

}

add_impl_default_members

Adds scaffold for overriding default impl members.

// BEFORE
trait T {
    Type X;
    fn foo(&self);
    fn bar(&self) {}
}

impl T for () {
    Type X = ();
    fn foo(&self) {}

}

// AFTER
trait T {
    Type X;
    fn foo(&self);
    fn bar(&self) {}
}

impl T for () {
    Type X = ();
    fn foo(&self) {}
    fn bar(&self) {}

}

add_impl_missing_members

Adds scaffold for required impl members.

// BEFORE
trait T {
    Type X;
    fn foo(&self);
    fn bar(&self) {}
}

impl T for () {

}

// AFTER
trait T {
    Type X;
    fn foo(&self);
    fn bar(&self) {}
}

impl T for () {
    fn foo(&self) { unimplemented!() }

}

add_import

Adds a use statement for a given fully-qualified path.

// BEFORE
fn process(map: std::collections::HashMap<String, String>) {}

// AFTER
use std::collections::HashMap;

fn process(map: HashMap<String, String>) {}

add_new

Adds a new inherent impl for a type.

// BEFORE
struct Ctx<T: Clone> {
     data: T,
}

// AFTER
struct Ctx<T: Clone> {
     data: T,
}

impl<T: Clone> Ctx<T> {
    fn new(data: T) -> Self { Self { data } }
}

apply_demorgan

Apply De Morgan's law. This transforms expressions of the form !l || !r into !(l && r). This also works with &&. This assist can only be applied with the cursor on either || or &&, with both operands being a negation of some kind. This means something of the form !x or x != y.

// BEFORE
fn main() {
    if x != 4 || !y {}
}

// AFTER
fn main() {
    if !(x == 4 && y) {}
}

change_visibility

Adds or changes existing visibility specifier.

// BEFORE
fn frobnicate() {}

// AFTER
pub(crate) fn frobnicate() {}

convert_to_guarded_return

Replace a large conditional with a guarded return.

// BEFORE
fn main() {
    if cond {
        foo();
        bar();
    }
}

// AFTER
fn main() {
    if !cond {
        return;
    }
    foo();
    bar();
}

fill_match_arms

Adds missing clauses to a match expression.

// BEFORE
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        
    }
}

// AFTER
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move { distance } => (),
        Action::Stop => (),
    }
}

flip_binexpr

Flips operands of a binary expression.

// BEFORE
fn main() {
    let _ = 90 + 2;
}

// AFTER
fn main() {
    let _ = 2 + 90;
}

flip_comma

Flips two comma-separated items.

// BEFORE
fn main() {
    ((1, 2), (3, 4));
}

// AFTER
fn main() {
    ((3, 4), (1, 2));
}

flip_trait_bound

Flips two trait bounds.

// BEFORE
fn foo<T: Clone + Copy>() { }

// AFTER
fn foo<T: Copy + Clone>() { }

inline_local_variable

Inlines local variable.

// BEFORE
fn main() {
    let x = 1 + 2;
    x * 4;
}

// AFTER
fn main() {
    (1 + 2) * 4;
}

introduce_variable

Extracts subexpression into a variable.

// BEFORE
fn main() {
    (1 + 2) * 4;
}

// AFTER
fn main() {
    let var_name = (1 + 2);
    var_name * 4;
}

make_raw_string

Adds r# to a plain string literal.

// BEFORE
fn main() {
    "Hello,┃ World!";
}

// AFTER
fn main() {
    r#"Hello, World!"#;
}

make_usual_string

Turns a raw string into a plain string.

// BEFORE
fn main() {
    r#"Hello,┃ "World!""#;
}

// AFTER
fn main() {
    "Hello, \"World!\"";
}

merge_match_arms

Merges identical match arms.

// BEFORE
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move(..) => foo(),
        Action::Stop => foo(),
    }
}

// AFTER
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move(..) | Action::Stop => foo(),
    }
}

move_arm_cond_to_match_guard

Moves if expression from match arm body into a guard.

// BEFORE
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move { distance } => if distance > 10 { foo() },
        _ => (),
    }
}

// AFTER
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move { distance } if distance > 10 => foo(),
        _ => (),
    }
}

move_bounds_to_where_clause

Moves inline type bounds to a where clause.

// BEFORE
fn apply<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {
    f(x)
}

// AFTER
fn apply<T, U, F>(f: F, x: T) -> U where F: FnOnce(T) -> U {
    f(x)
}

move_guard_to_arm_body

Moves match guard into match arm body.

// BEFORE
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move { distance } if distance > 10 => foo(),
        _ => (),
    }
}

// AFTER
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move { distance } => if distance > 10 { foo() },
        _ => (),
    }
}

remove_dbg

Removes dbg!() macro call.

// BEFORE
fn main() {
    dbg!(92);
}

// AFTER
fn main() {
    92;
}

remove_hash

Removes a hash from a raw string literal.

// BEFORE
fn main() {
    r#"Hello,┃ World!"#;
}

// AFTER
fn main() {
    r"Hello, World!";
}

replace_if_let_with_match

Replaces if let with an else branch with a match expression.

// BEFORE
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    if let Action::Move { distance } = action {
        foo(distance)
    } else {
        bar()
    }
}

// AFTER
enum Action { Move { distance: u32 }, Stop }

fn handle(action: Action) {
    match action {
        Action::Move { distance } => foo(distance),
        _ => bar(),
    }
}

split_import

Wraps the tail of import into braces.

// BEFORE
use std::collections::HashMap;

// AFTER
use std::{collections::HashMap};