From 994006585be6850b250b21aac76a58f1324cad5d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Jun 2020 11:16:49 +0200 Subject: Start documenting review process --- docs/dev/README.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/dev/README.md b/docs/dev/README.md index 65cc9fc12..1de5a2aab 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md @@ -30,7 +30,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0 * [good-first-issue](https://github.com/rust-analyzer/rust-analyzer/labels/good%20first%20issue) are good issues to get into the project. -* [E-mentor](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-mentor) +* [E-has-instructions](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-has-instructions) issues have links to the code in question and tests. * [E-easy](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy), [E-medium](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-medium), @@ -117,6 +117,109 @@ Additionally, I use `cargo run --release -p rust-analyzer -- analysis-stats path/to/some/rust/crate` to run a batch analysis. This is primarily useful for performance optimizations, or for bug minimization. +# Code Style & Review Process + +Our approach to "clean code" is two fold: + +* We generally don't block PRs on style changes. +* At the same time, all code in rust-analyzer is constantly refactored. + +It is explicitly OK for reviewer to flag only some nits in the PR, and than send a follow up cleanup PR for things which are easier to explain by example, cc-ing the original author. +Sending small cleanup PRs (like rename a single local variable) is encouraged. + +## Scale of Changes + +Everyone knows that it's better to send small & focused pull requests. +The problem is, sometimes you *have* to, eg, rewrite the whole compiler, and that just doesn't fit into a set of isolated PRs. + +The main thing too keep an eye on is the boundaries between various components. +There are three kinds of changes: + +1. Internals of a single component are changed. + Specifically, you don't change any `pub` items. + A good example here would be an addition of a new assist. + +2. API of a component is expanded. + Specifically, you add a new `pub` function which wasn't there before. + A good example here would be expansion of assist API, for example, to implement lazy assists or assists groups. + +3. A new dependency between components is introduced. + Specifically, you add a `pub use` reexport from another crate or you add a new line to `[dependencies]` section of `Cargo.toml`. + A good example here would be adding reference search capability to the assists crates. + +For the first group, the change is generally merged as long as: + +* it works for the happy case, +* it has tests, +* it doesn't panic for unhappy case. + +For the second group, the change would be subjected to quite a bit of scrutiny and iteration. +The new API needs to be right (or at least easy to change later). +The actual implementation doesn't matter that much. +It's very important to minimize the amount of changed lines of code for changes of the second kind. +Often, you start doing change of the first kind, only to realise that you need to elevate to a change of the second kind. +In this case, we'll probably ask you to split API changes into a separate PR. + +Changes of the third group should be pretty rare, so we don't specify any specific process for them. +That said, adding an innocent-looking `pub use` is a very simple way to break encapsulation, keep an eye on it! + +Note: if you enjoyed this abstract hand-waving about boundaries, you might appreciate +https://www.tedinski.com/2018/02/06/system-boundaries.html + +## Order of Imports + +We separate import groups with blank lines + +``` +mod x; +mod y; + +use std::{ ... } + +use crate_foo::{ ... } +use crate_bar::{ ... } + +use crate::{} + +use super::{} // but prefer `use crate::` +``` + +## Order of Items + +Optimize for the reader who sees the file for the first time, and wants to get the general idea about what's going on. +People read things from top to bottom, so place most important things first. + +Specifically, if all items except one are private, always put the non-private item on top. + +Put `struct`s and `enum`s first, functions and impls last. + +Do + +``` +// Good +struct Foo { + bars: Vec +} + +struct Bar; +``` + +rather than + +``` +// Not as good +struct Bar; + +struct Foo { + bars: Vec +} +``` + +## Documentation + +For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. +If the line is too long, you want to split the sentence in two :-) + # Logging Logging is done by both rust-analyzer and VS Code, so it might be tricky to -- cgit v1.2.3 From ed866892640214d315d3e9503ccaed96ca87ccc0 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Wed, 3 Jun 2020 06:55:27 -0400 Subject: Update generated feature docs --- docs/user/generated_features.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/user/generated_features.adoc b/docs/user/generated_features.adoc index 12812fa0b..4b93b759f 100644 --- a/docs/user/generated_features.adoc +++ b/docs/user/generated_features.adoc @@ -76,7 +76,7 @@ Navigates to the type of an identifier. === Hover -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/hover.rs#L63[hover.rs] +**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/hover.rs#L58[hover.rs] Shows additional information, like type of an expression or documentation for definition when "focusing" code. Focusing is usually hovering with a mouse, but can also be triggered with a shortcut. -- cgit v1.2.3 From fa019c8f562326a720d2ef9165626c4c5703f67b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 3 Jun 2020 14:48:38 +0200 Subject: Document rust-project.json --- docs/user/manual.adoc | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'docs') diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc index 202783fd9..ea714f49a 100644 --- a/docs/user/manual.adoc +++ b/docs/user/manual.adoc @@ -269,6 +269,57 @@ Gnome Builder currently has support for RLS, and there's no way to configure the 1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). 2. Enable the Rust Builder plugin. +== Non-Cargo Based Projects + +rust-analyzer does not require Cargo. +However, if you use some other build system, you'll have to describe the structure of your project for rust-analyzer in the `rust-project.json` format: + +[source,TypeScript] +---- +interface JsonProject { + /// The set of paths containing the crates for this project. + /// Any `Crate` must be nested inside some `root`. + roots: string[]; + /// The set of crates comprising the current project. + /// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such). + crates: Crate[]; +} + +interface Crate { + /// Path to the root module of the crate. + root_module: string; + /// Edition of the crate. + edition: "2015" | "2018"; + /// Dependencies + deps: Dep[]; + /// The set of cfgs activated for a given crate, like `["unix", "feature=foo", "feature=bar"]`. + cfg: string[]; + + /// value of the OUT_DIR env variable. + out_dir?: string; + /// For proc-macro crates, path to compiles proc-macro (.so file). + proc_macro_dylib_path?: string; +} + +interface Dep { + /// Index of a crate in the `crates` array. + crate: number, + /// Name as should appear in the (implicit) `extern crate name` declaration. + name: string, +} +---- + +This format is provisional and subject to change. +Specifically, the `roots` setup will be different eventually. + +There are tree ways to feed `rust-project.json` to rust-analyzer: + +* Place `rust-project.json` file at the root of the project, and rust-anlayzer will discover it. +* Specify `"rust-analyzer.linkedProjects": [ "path/to/rust-project.json" ]` in the settings (and make sure that your LSP client sends settings as a part of initialize request). +* Specify `"rust-analyzer.linkedProjects": [ { "roots": [...], "crates": [...] }]` inline. + +See https://github.com/rust-analyzer/rust-project.json-example for a small example. + == Features include::./generated_features.adoc[] -- cgit v1.2.3 From 5315934d888797432d62ec4a55303aeacb8cd286 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 3 Jun 2020 18:22:05 +0200 Subject: Don't store generated docs in the repo --- docs/user/generated_assists.adoc | 1015 ------------------------------------- docs/user/generated_features.adoc | 298 ----------- 2 files changed, 1313 deletions(-) delete mode 100644 docs/user/generated_assists.adoc delete mode 100644 docs/user/generated_features.adoc (limited to 'docs') diff --git a/docs/user/generated_assists.adoc b/docs/user/generated_assists.adoc deleted file mode 100644 index 4d2fb31d4..000000000 --- a/docs/user/generated_assists.adoc +++ /dev/null @@ -1,1015 +0,0 @@ -[discrete] -=== `add_custom_impl` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_custom_impl.rs#L14[add_custom_impl.rs] - -Adds impl block for derived trait. - -.Before -```rust -#[derive(Deb┃ug, Display)] -struct S; -``` - -.After -```rust -#[derive(Display)] -struct S; - -impl Debug for S { - $0 -} -``` - - -[discrete] -=== `add_derive` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_derive.rs#L9[add_derive.rs] - -Adds a new `#[derive()]` clause to a struct or enum. - -.Before -```rust -struct Point { - x: u32, - y: u32,┃ -} -``` - -.After -```rust -#[derive($0)] -struct Point { - x: u32, - y: u32, -} -``` - - -[discrete] -=== `add_explicit_type` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_explicit_type.rs#L9[add_explicit_type.rs] - -Specify type for a let binding. - -.Before -```rust -fn main() { - let x┃ = 92; -} -``` - -.After -```rust -fn main() { - let x: i32 = 92; -} -``` - - -[discrete] -=== `add_from_impl_for_enum` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs#L7[add_from_impl_for_enum.rs] - -Adds a From impl for an enum variant with one tuple field. - -.Before -```rust -enum A { ┃One(u32) } -``` - -.After -```rust -enum A { One(u32) } - -impl From for A { - fn from(v: u32) -> Self { - A::One(v) - } -} -``` - - -[discrete] -=== `add_function` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_function.rs#L19[add_function.rs] - -Adds a stub function with a signature matching the function under the cursor. - -.Before -```rust -struct Baz; -fn baz() -> Baz { Baz } -fn foo() { - bar┃("", baz()); -} - -``` - -.After -```rust -struct Baz; -fn baz() -> Baz { Baz } -fn foo() { - bar("", baz()); -} - -fn bar(arg: &str, baz: Baz) { - ${0:todo!()} -} - -``` - - -[discrete] -=== `add_hash` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L65[raw_string.rs] - -Adds a hash to a raw string literal. - -.Before -```rust -fn main() { - r#"Hello,┃ World!"#; -} -``` - -.After -```rust -fn main() { - r##"Hello, World!"##; -} -``` - - -[discrete] -=== `add_impl` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_impl.rs#L6[add_impl.rs] - -Adds a new inherent impl for a type. - -.Before -```rust -struct Ctx { - data: T,┃ -} -``` - -.After -```rust -struct Ctx { - data: T, -} - -impl Ctx { - $0 -} -``` - - -[discrete] -=== `add_impl_default_members` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_missing_impl_members.rs#L64[add_missing_impl_members.rs] - -Adds scaffold for overriding default impl members. - -.Before -```rust -trait Trait { - Type X; - fn foo(&self); - fn bar(&self) {} -} - -impl Trait for () { - Type X = (); - fn foo(&self) {}┃ - -} -``` - -.After -```rust -trait Trait { - Type X; - fn foo(&self); - fn bar(&self) {} -} - -impl Trait for () { - Type X = (); - fn foo(&self) {} - $0fn bar(&self) {} - -} -``` - - -[discrete] -=== `add_impl_missing_members` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_missing_impl_members.rs#L24[add_missing_impl_members.rs] - -Adds scaffold for required impl members. - -.Before -```rust -trait Trait { - Type X; - fn foo(&self) -> T; - fn bar(&self) {} -} - -impl Trait for () {┃ - -} -``` - -.After -```rust -trait Trait { - Type X; - fn foo(&self) -> T; - fn bar(&self) {} -} - -impl Trait for () { - fn foo(&self) -> u32 { - ${0:todo!()} - } - -} -``` - - -[discrete] -=== `add_new` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_new.rs#L12[add_new.rs] - -Adds a new inherent impl for a type. - -.Before -```rust -struct Ctx { - data: T,┃ -} -``` - -.After -```rust -struct Ctx { - data: T, -} - -impl Ctx { - fn $0new(data: T) -> Self { Self { data } } -} - -``` - - -[discrete] -=== `add_turbo_fish` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_turbo_fish.rs#L10[add_turbo_fish.rs] - -Adds `::<_>` to a call of a generic method or function. - -.Before -```rust -fn make() -> T { todo!() } -fn main() { - let x = make┃(); -} -``` - -.After -```rust -fn make() -> T { todo!() } -fn main() { - let x = make::<${0:_}>(); -} -``` - - -[discrete] -=== `apply_demorgan` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/apply_demorgan.rs#L5[apply_demorgan.rs] - -Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). -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 -```rust -fn main() { - if x != 4 ||┃ !y {} -} -``` - -.After -```rust -fn main() { - if !(x == 4 && y) {} -} -``` - - -[discrete] -=== `auto_import` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/auto_import.rs#L18[auto_import.rs] - -If the name is unresolved, provides all possible imports for it. - -.Before -```rust -fn main() { - let map = HashMap┃::new(); -} -``` - -.After -```rust -use std::collections::HashMap; - -fn main() { - let map = HashMap::new(); -} -``` - - -[discrete] -=== `change_return_type_to_result` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/change_return_type_to_result.rs#L8[change_return_type_to_result.rs] - -Change the function's return type to Result. - -.Before -```rust -fn foo() -> i32┃ { 42i32 } -``` - -.After -```rust -fn foo() -> Result { Ok(42i32) } -``` - - -[discrete] -=== `change_visibility` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/change_visibility.rs#L14[change_visibility.rs] - -Adds or changes existing visibility specifier. - -.Before -```rust -┃fn frobnicate() {} -``` - -.After -```rust -pub(crate) fn frobnicate() {} -``` - - -[discrete] -=== `convert_to_guarded_return` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/early_return.rs#L21[early_return.rs] - -Replace a large conditional with a guarded return. - -.Before -```rust -fn main() { - ┃if cond { - foo(); - bar(); - } -} -``` - -.After -```rust -fn main() { - if !cond { - return; - } - foo(); - bar(); -} -``` - - -[discrete] -=== `fill_match_arms` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/fill_match_arms.rs#L14[fill_match_arms.rs] - -Adds missing clauses to a `match` expression. - -.Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - ┃ - } -} -``` - -.After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - $0Action::Move { distance } => {} - Action::Stop => {} - } -} -``` - - -[discrete] -=== `fix_visibility` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/fix_visibility.rs#L13[fix_visibility.rs] - -Makes inaccessible item public. - -.Before -```rust -mod m { - fn frobnicate() {} -} -fn main() { - m::frobnicate┃() {} -} -``` - -.After -```rust -mod m { - $0pub(crate) fn frobnicate() {} -} -fn main() { - m::frobnicate() {} -} -``` - - -[discrete] -=== `flip_binexpr` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/flip_binexpr.rs#L5[flip_binexpr.rs] - -Flips operands of a binary expression. - -.Before -```rust -fn main() { - let _ = 90 +┃ 2; -} -``` - -.After -```rust -fn main() { - let _ = 2 + 90; -} -``` - - -[discrete] -=== `flip_comma` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/flip_comma.rs#L5[flip_comma.rs] - -Flips two comma-separated items. - -.Before -```rust -fn main() { - ((1, 2),┃ (3, 4)); -} -``` - -.After -```rust -fn main() { - ((3, 4), (1, 2)); -} -``` - - -[discrete] -=== `flip_trait_bound` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/flip_trait_bound.rs#L9[flip_trait_bound.rs] - -Flips two trait bounds. - -.Before -```rust -fn foo() { } -``` - -.After -```rust -fn foo() { } -``` - - -[discrete] -=== `inline_local_variable` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/inline_local_variable.rs#L13[inline_local_variable.rs] - -Inlines local variable. - -.Before -```rust -fn main() { - let x┃ = 1 + 2; - x * 4; -} -``` - -.After -```rust -fn main() { - (1 + 2) * 4; -} -``` - - -[discrete] -=== `introduce_named_lifetime` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/introduce_named_lifetime.rs#L12[introduce_named_lifetime.rs] - -Change an anonymous lifetime to a named lifetime. - -.Before -```rust -impl Cursor<'_┃> { - fn node(self) -> &SyntaxNode { - match self { - Cursor::Replace(node) | Cursor::Before(node) => node, - } - } -} -``` - -.After -```rust -impl<'a> Cursor<'a> { - fn node(self) -> &SyntaxNode { - match self { - Cursor::Replace(node) | Cursor::Before(node) => node, - } - } -} -``` - - -[discrete] -=== `introduce_variable` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/introduce_variable.rs#L14[introduce_variable.rs] - -Extracts subexpression into a variable. - -.Before -```rust -fn main() { - ┃(1 + 2)┃ * 4; -} -``` - -.After -```rust -fn main() { - let $0var_name = (1 + 2); - var_name * 4; -} -``` - - -[discrete] -=== `invert_if` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/invert_if.rs#L12[invert_if.rs] - -Apply invert_if -This transforms if expressions of the form `if !x {A} else {B}` into `if x {B} else {A}` -This also works with `!=`. This assist can only be applied with the cursor -on `if`. - -.Before -```rust -fn main() { - if┃ !y { A } else { B } -} -``` - -.After -```rust -fn main() { - if y { B } else { A } -} -``` - - -[discrete] -=== `make_raw_string` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L10[raw_string.rs] - -Adds `r#` to a plain string literal. - -.Before -```rust -fn main() { - "Hello,┃ World!"; -} -``` - -.After -```rust -fn main() { - r#"Hello, World!"#; -} -``` - - -[discrete] -=== `make_usual_string` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L39[raw_string.rs] - -Turns a raw string into a plain string. - -.Before -```rust -fn main() { - r#"Hello,┃ "World!""#; -} -``` - -.After -```rust -fn main() { - "Hello, \"World!\""; -} -``` - - -[discrete] -=== `merge_imports` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/merge_imports.rs#L14[merge_imports.rs] - -Merges two imports with a common prefix. - -.Before -```rust -use std::┃fmt::Formatter; -use std::io; -``` - -.After -```rust -use std::{fmt::Formatter, io}; -``` - - -[discrete] -=== `merge_match_arms` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/merge_match_arms.rs#L11[merge_match_arms.rs] - -Merges identical match arms. - -.Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - ┃Action::Move(..) => foo(), - Action::Stop => foo(), - } -} -``` - -.After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move(..) | Action::Stop => foo(), - } -} -``` - - -[discrete] -=== `move_arm_cond_to_match_guard` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/move_guard.rs#L56[move_guard.rs] - -Moves if expression from match arm body into a guard. - -.Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => ┃if distance > 10 { foo() }, - _ => (), - } -} -``` - -.After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } if distance > 10 => foo(), - _ => (), - } -} -``` - - -[discrete] -=== `move_bounds_to_where_clause` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/move_bounds.rs#L10[move_bounds.rs] - -Moves inline type bounds to a where clause. - -.Before -```rust -fn apply U>(f: F, x: T) -> U { - f(x) -} -``` - -.After -```rust -fn apply(f: F, x: T) -> U where F: FnOnce(T) -> U { - f(x) -} -``` - - -[discrete] -=== `move_guard_to_arm_body` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/move_guard.rs#L8[move_guard.rs] - -Moves match guard into match arm body. - -.Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } ┃if distance > 10 => foo(), - _ => (), - } -} -``` - -.After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => if distance > 10 { foo() }, - _ => (), - } -} -``` - - -[discrete] -=== `remove_dbg` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/remove_dbg.rs#L8[remove_dbg.rs] - -Removes `dbg!()` macro call. - -.Before -```rust -fn main() { - ┃dbg!(92); -} -``` - -.After -```rust -fn main() { - 92; -} -``` - - -[discrete] -=== `remove_hash` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L89[raw_string.rs] - -Removes a hash from a raw string literal. - -.Before -```rust -fn main() { - r#"Hello,┃ World!"#; -} -``` - -.After -```rust -fn main() { - r"Hello, World!"; -} -``` - - -[discrete] -=== `remove_mut` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/remove_mut.rs#L5[remove_mut.rs] - -Removes the `mut` keyword. - -.Before -```rust -impl Walrus { - fn feed(&mut┃ self, amount: u32) {} -} -``` - -.After -```rust -impl Walrus { - fn feed(&self, amount: u32) {} -} -``` - - -[discrete] -=== `reorder_fields` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/reorder_fields.rs#L10[reorder_fields.rs] - -Reorder the fields of record literals and record patterns in the same order as in -the definition. - -.Before -```rust -struct Foo {foo: i32, bar: i32}; -const test: Foo = ┃Foo {bar: 0, foo: 1} -``` - -.After -```rust -struct Foo {foo: i32, bar: i32}; -const test: Foo = Foo {foo: 1, bar: 0} -``` - - -[discrete] -=== `replace_if_let_with_match` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_if_let_with_match.rs#L13[replace_if_let_with_match.rs] - -Replaces `if let` with an else branch with a `match` expression. - -.Before -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - ┃if let Action::Move { distance } = action { - foo(distance) - } else { - bar() - } -} -``` - -.After -```rust -enum Action { Move { distance: u32 }, Stop } - -fn handle(action: Action) { - match action { - Action::Move { distance } => foo(distance), - _ => bar(), - } -} -``` - - -[discrete] -=== `replace_let_with_if_let` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_let_with_if_let.rs#L14[replace_let_with_if_let.rs] - -Replaces `let` with an `if-let`. - -.Before -```rust - -fn main(action: Action) { - ┃let x = compute(); -} - -fn compute() -> Option { None } -``` - -.After -```rust - -fn main(action: Action) { - if let Some(x) = compute() { - } -} - -fn compute() -> Option { None } -``` - - -[discrete] -=== `replace_qualified_name_with_use` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs#L6[replace_qualified_name_with_use.rs] - -Adds a use statement for a given fully-qualified name. - -.Before -```rust -fn process(map: std::collections::┃HashMap) {} -``` - -.After -```rust -use std::collections::HashMap; - -fn process(map: HashMap) {} -``` - - -[discrete] -=== `replace_unwrap_with_match` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs#L17[replace_unwrap_with_match.rs] - -Replaces `unwrap` a `match` expression. Works for Result and Option. - -.Before -```rust -enum Result { Ok(T), Err(E) } -fn main() { - let x: Result = Result::Ok(92); - let y = x.┃unwrap(); -} -``` - -.After -```rust -enum Result { Ok(T), Err(E) } -fn main() { - let x: Result = Result::Ok(92); - let y = match x { - Ok(a) => a, - $0_ => unreachable!(), - }; -} -``` - - -[discrete] -=== `split_import` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/split_import.rs#L7[split_import.rs] - -Wraps the tail of import into braces. - -.Before -```rust -use std::┃collections::HashMap; -``` - -.After -```rust -use std::{collections::HashMap}; -``` - - -[discrete] -=== `unwrap_block` -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/unwrap_block.rs#L9[unwrap_block.rs] - -This assist removes if...else, for, while and loop control statements to just keep the body. - -.Before -```rust -fn foo() { - if true {┃ - println!("foo"); - } -} -``` - -.After -```rust -fn foo() { - println!("foo"); -} -``` diff --git a/docs/user/generated_features.adoc b/docs/user/generated_features.adoc deleted file mode 100644 index 4b93b759f..000000000 --- a/docs/user/generated_features.adoc +++ /dev/null @@ -1,298 +0,0 @@ -=== Expand Macro Recursively -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/expand_macro.rs#L15[expand_macro.rs] - -Shows the full macro expansion of the macro at current cursor. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Expand macro recursively** -|=== - - -=== Extend Selection -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/extend_selection.rs#L15[extend_selection.rs] - -Extends the current selection to the encompassing syntactic construct -(expression, statement, item, module, etc). It works with multiple cursors. - -|=== -| Editor | Shortcut - -| VS Code | kbd:[Ctrl+Shift+→] -|=== - - -=== File Structure -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/display/structure.rs#L17[structure.rs] - -Provides a tree of the symbols defined in the file. Can be used to - -* fuzzy search symbol in a file (super useful) -* draw breadcrumbs to describe the context around the cursor -* draw outline of the file - -|=== -| Editor | Shortcut - -| VS Code | kbd:[Ctrl+Shift+O] -|=== - - -=== Go to Definition -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_definition.rs#L18[goto_definition.rs] - -Navigates to the definition of an identifier. - -|=== -| Editor | Shortcut - -| VS Code | kbd:[F12] -|=== - - -=== Go to Implementation -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_implementation.rs#L7[goto_implementation.rs] - -Navigates to the impl block of structs, enums or traits. Also implemented as a code lens. - -|=== -| Editor | Shortcut - -| VS Code | kbd:[Ctrl+F12] -|=== - - -=== Go to Type Definition -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_type_definition.rs#L6[goto_type_definition.rs] - -Navigates to the type of an identifier. - -|=== -| Editor | Action Name - -| VS Code | **Go to Type Definition* -|=== - - -=== Hover -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/hover.rs#L58[hover.rs] - -Shows additional information, like type of an expression or documentation for definition when "focusing" code. -Focusing is usually hovering with a mouse, but can also be triggered with a shortcut. - - -=== Inlay Hints -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/inlay_hints.rs#L40[inlay_hints.rs] - -rust-analyzer shows additional information inline with the source code. -Editors usually render this using read-only virtual text snippets interspersed with code. - -rust-analyzer shows hits for - -* types of local variables -* names of function arguments -* types of chained expressions - -**Note:** VS Code does not have native support for inlay hints https://github.com/microsoft/vscode/issues/16221[yet] and the hints are implemented using decorations. -This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird: -https://github.com/rust-analyzer/rust-analyzer/issues/1623[1], https://github.com/rust-analyzer/rust-analyzer/issues/3453[2]. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Toggle inlay hints* -|=== - - -=== Join Lines -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/join_lines.rs#L12[join_lines.rs] - -Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Join lines** -|=== - - -=== Magic Completions -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/completion.rs#L38[completion.rs] - -In addition to usual reference completion, rust-analyzer provides some ✨magic✨ -completions as well: - -Keywords like `if`, `else` `while`, `loop` are completed with braces, and cursor -is placed at the appropriate position. Even though `if` is easy to type, you -still want to complete it, to get ` { }` for free! `return` is inserted with a -space or `;` depending on the return type of the function. - -When completing a function call, `()` are automatically inserted. If a function -takes arguments, the cursor is positioned inside the parenthesis. - -There are postfix completions, which can be triggered by typing something like -`foo().if`. The word after `.` determines postfix completion. Possible variants are: - -- `expr.if` -> `if expr {}` or `if let ... {}` for `Option` or `Result` -- `expr.match` -> `match expr {}` -- `expr.while` -> `while expr {}` or `while let ... {}` for `Option` or `Result` -- `expr.ref` -> `&expr` -- `expr.refm` -> `&mut expr` -- `expr.not` -> `!expr` -- `expr.dbg` -> `dbg!(expr)` - -There also snippet completions: - -.Expressions -- `pd` -> `println!("{:?}")` -- `ppd` -> `println!("{:#?}")` - -.Items -- `tfn` -> `#[test] fn f(){}` -- `tmod` -> -```rust -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_fn() {} -} -``` - - -=== Matching Brace -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/matching_brace.rs#L3[matching_brace.rs] - -If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair, -moves cursor to the matching brace. It uses the actual parser to determine -braces, so it won't confuse generics with comparisons. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Find matching brace** -|=== - - -=== On Typing Assists -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/typing.rs#L35[typing.rs] - -Some features trigger on typing certain characters: - -- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression -- Enter inside comments automatically inserts `///` -- typing `.` in a chain method call auto-indents - - -=== Parent Module -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/parent_module.rs#L12[parent_module.rs] - -Navigates to the parent module of the current module. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Locate parent module** -|=== - - -=== Run -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/runnables.rs#L45[runnables.rs] - -Shows a popup suggesting to run a test/benchmark/binary **at the current cursor -location**. Super useful for repeatedly running just a single test. Do bind this -to a shortcut! - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Run** -|=== - - -=== Semantic Syntax Highlighting -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/syntax_highlighting.rs#L33[syntax_highlighting.rs] - -rust-analyzer highlights the code semantically. -For example, `bar` in `foo::Bar` might be colored differently depending on whether `Bar` is an enum or a trait. -rust-analyzer does not specify colors directly, instead it assigns tag (like `struct`) and a set of modifiers (like `declaration`) to each token. -It's up to the client to map those to specific colors. - -The general rule is that a reference to an entity gets colored the same way as the entity itself. -We also give special modifier for `mut` and `&mut` local variables. - - -=== Show Syntax Tree -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/syntax_tree.rs#L9[syntax_tree.rs] - -Shows the parse tree of the current file. It exists mostly for debugging -rust-analyzer itself. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Show Syntax Tree** -|=== - - -=== Status -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/status.rs#L27[status.rs] - -Shows internal statistic about memory usage of rust-analyzer. - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Status** -|=== - - -=== Structural Seach and Replace -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/ssr.rs#L26[ssr.rs] - -Search and replace with named wildcards that will match any expression. -The syntax for a structural search replace command is ` ==>> `. -A `$:expr` placeholder in the search pattern will match any expression and `$` will reference it in the replacement. -Available via the command `rust-analyzer.ssr`. - -```rust -// Using structural search replace command [foo($a:expr, $b:expr) ==>> ($a).foo($b)] - -// BEFORE -String::from(foo(y + 5, z)) - -// AFTER -String::from((y + 5).foo(z)) -``` - -|=== -| Editor | Action Name - -| VS Code | **Rust Analyzer: Structural Search Replace** -|=== - - -=== Workspace Symbol -**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide_db/src/symbol_index.rs#L113[symbol_index.rs] - -Uses fuzzy-search to find types, modules and functions by name across your -project and dependencies. This is **the** most useful feature, which improves code -navigation tremendously. It mostly works on top of the built-in LSP -functionality, however `#` and `*` symbols can be used to narrow down the -search. Specifically, - -- `Foo` searches for `Foo` type in the current workspace -- `foo#` searches for `foo` function in the current workspace -- `Foo*` searches for `Foo` type among dependencies, including `stdlib` -- `foo#*` searches for `foo` function among dependencies - -That is, `#` switches from "types" to all symbols, `*` switches from the current -workspace to dependencies. - -|=== -| Editor | Shortcut - -| VS Code | kbd:[Ctrl+T] -|=== -- cgit v1.2.3