Source: annotations.rs
Provides user with annotations above items for looking up references or impl blocks and running/debugging binaries.
Source: auto_import.rs
Using the auto-import
assist it is possible to insert missing imports for unresolved items.
When inserting an import it will do so in a structured manner by keeping imports grouped,
separated by a newline in the following order:
-
std
andcore
-
External Crates
-
Current Crate, paths prefixed by
crate
-
Current Module, paths prefixed by
self
-
Super Module, paths prefixed by
super
Example:
use std::fs::File;
use itertools::Itertools;
use syntax::ast;
use crate::utils::insert_use;
use self::auto_import;
use super::AssistContext;
It is possible to configure how use-trees are merged with the importGranularity
setting.
It has the following configurations:
-
crate
: Merge imports from the same crate into a single use statement. This kind of nesting is only supported in Rust versions later than 1.24. -
module
: Merge imports from the same module into a single use statement. -
item
: Don’t merge imports at all, creating one import per item. -
preserve
: Do not change the granularity of any imports. For auto-import this has the same effect asitem
.
In VS Code
the configuration for this is rust-analyzer.assist.importGranularity
.
The style of imports in the same crate is configurable through the importPrefix
setting.
It has the following configurations:
-
by_crate
: This setting will force paths to be always absolute, starting with thecrate
prefix, unless the item is defined outside of the current crate. -
by_self
: This setting will force paths that are relative to the current module to always start withself
. This will result in paths that always start with eithercrate
,self
,super
or an extern crate identifier. -
plain
: This setting does not impose any restrictions in imports.
In VS Code
the configuration for this is rust-analyzer.assist.importPrefix
.
Source: view_item_tree.rs
Displays the ItemTree of the currently open file, for debugging.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Debug ItemTree |
Source: expand_macro.rs
Shows the full macro expansion of the macro at current cursor.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Expand macro recursively |
Source: extend_selection.rs
Extends or shrinks the current selection to the encompassing syntactic construct (expression, statement, item, module, etc). It works with multiple cursors.
This is a standard LSP feature and not a protocol extension.
Editor | Shortcut |
---|---|
VS Code |
kbd:[Alt+Shift+→], kbd:[Alt+Shift+←] |
Source: file_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] |
Source: references.rs
Shows all references of the item at the cursor location
Editor | Shortcut |
---|---|
VS Code |
kbd:[Shift+Alt+F12] |
Source: folding_ranges.rs
Defines folding regions for curly braced blocks, runs of consecutive use, mod, const or static
items, and region
/ endregion
comment markers.
Source: format_like.rs
"Result {result} is {2 + 2}"
is expanded to the "Result {} is {}", result, 2 + 2
.
The following postfix snippets are available:
-
format
→format!(…)
-
panic
→panic!(…)
-
println
→println!(…)
-
log
:-
logd
→log::debug!(…)
-
logt
→log::trace!(…)
-
logi
→log::info!(…)
-
logw
→log::warn!(…)
-
loge
→log::error!(…)
-
Source: goto_declaration.rs
Navigates to the declaration of an identifier.
Source: goto_definition.rs
Navigates to the definition of an identifier.
Editor | Shortcut |
---|---|
VS Code |
kbd:[F12] |
Source: 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] |
Source: goto_type_definition.rs
Navigates to the type of an identifier.
Editor | Action Name |
---|---|
VS Code |
*Go to Type Definition |
Source: highlight_related.rs
Highlights constructs related to the thing under the cursor:
- if on an identifier, highlights all references to that identifier in the current file
- if on an async
or await token, highlights all yield points for that async context
- if on a `return
token, ?
character or →
return type arrow, highlights all exit points for that context
- if on a break
, loop
, while
or for
token, highlights all break points for that loop or block context
Source: hover.rs
Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code. Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
Source: 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 hints for
-
types of local variables
-
names of function arguments
-
types of chained expressions
Note: VS Code does not have native support for inlay hints 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: 1, 2.
Editor | Action Name |
---|---|
VS Code |
*Rust Analyzer: Toggle inlay hints |
Source: join_lines.rs
Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces.
See this gif for the cases handled specially by joined lines.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Join lines |
Source: lib.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 {}
orif let … {}
forOption
orResult
-
expr.match
→match expr {}
-
expr.while
→while expr {}
orwhile let … {}
forOption
orResult
-
expr.ref
→&expr
-
expr.refm
→&mut expr
-
expr.let
→let $0 = expr;
-
expr.letm
→let mut $0 = expr;
-
expr.not
→!expr
-
expr.dbg
→dbg!(expr)
-
expr.dbgr
→dbg!(&expr)
-
expr.call
→(expr)
There also snippet completions:
-
pd
→eprintln!(" = {:?}", );
-
ppd
→eprintln!(" = {:#?}", );
-
tfn
→#[test] fn feature(){}
-
tmod
→
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_name() {}
}
And the auto import completions, enabled with the rust-analyzer.completion.autoimport.enable
setting and the corresponding LSP client capabilities.
Those are the additional completion options with automatic use
import and options from all project importable items,
fuzzy matched against the completion input.
Source: 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 |
Source: apply_change.rs
Clears rust-analyzer’s internal database and prints memory usage statistics.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Memory Usage (Clears Database) |
Source: move_item.rs
Move item under cursor or selection up and down.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Move item up |
VS Code |
Rust Analyzer: Move item down |
Source: on_enter.rs
rust-analyzer can override kbd:[Enter] key to make it smarter:
-
kbd:[Enter] inside triple-slash comments automatically inserts
///
-
kbd:[Enter] in the middle or after a trailing space in
//
inserts//
-
kbd:[Enter] inside
//!
doc comments automatically inserts//!
-
kbd:[Enter] after
{
indents contents and closing}
of single-line block
This action needs to be assigned to shortcut explicitly.
- VS Code
-
Add the following to
keybindings.json
:
{
"key": "Enter",
"command": "rust-analyzer.onEnter",
"when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust"
}
Source: typing.rs
Some features trigger on typing certain characters:
-
typing
let =
tries to smartly add;
if=
is followed by an existing expression -
typing
.
in a chain method call auto-indents -
typing
{
in front of an expression inserts a closing}
after the expression- VS Code
-
Add the following to
settings.json
:
"editor.formatOnType": true,
Source: parent_module.rs
Navigates to the parent module of the current module.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Locate parent module |
Source: runnables.rs
Provides a sneak peek of all tests where the current item is used.
The simplest way to use this feature is via the context menu: - Right-click on the selected item. The context menu opens. - Select Peek related tests
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Peek related tests |
Source: rename.rs
Renames the item below the cursor and all of its references
Editor | Shortcut |
---|---|
VS Code |
kbd:[F2] |
Source: 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 |
Source: 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 a 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.
Rust-analyzer currently emits the following token tags:
-
For items:
enum Emitted for enums.
function Emitted for free-standing functions.
macro Emitted for macros.
method Emitted for associated functions, also knowns as methods.
namespace Emitted for modules.
struct Emitted for structs.
trait Emitted for traits.
typeAlias Emitted for type aliases and
Self
in `impl`s.union Emitted for unions.
-
For literals:
boolean Emitted for the boolean literals
true
andfalse
.character Emitted for character literals.
number Emitted for numeric literals.
string Emitted for string literals.
escapeSequence Emitted for escaped sequences inside strings like
\n
.formatSpecifier Emitted for format specifiers
{:?}
informat!
-like macros. -
For operators:
operator Emitted for general operators.
arithmetic Emitted for the arithmetic operators
`, `-`, `*`, `/`, `=
,-=
,*=
,/=
.bitwise Emitted for the bitwise operators
|
,&
,!
,^
,|=
,&=
,^=
.comparison Emitted for the comparison operators
>
,<
,==
,>=
,⇐
,!=
.logical Emitted for the logical operators
||
,&&
,!
. -
For punctuation:
punctuation Emitted for general punctuation.
angle Emitted for
<>
angle brackets.brace Emitted for
{}
braces.bracket Emitted for
[]
brackets.parenthesis Emitted for
()
parentheses.colon Emitted for the
:
token.comma Emitted for the
,
token.dot Emitted for the
.
token.Semi Emitted for the
;
token.
attribute |
Emitted for the |
builtinAttribute |
Emitted for names to builtin attributes in attribute path, the |
builtinType |
Emitted for builtin types like |
comment |
Emitted for comments. |
constParameter |
Emitted for const parameters. |
enumMember |
Emitted for enum variants. |
generic |
Emitted for generic tokens that have no mapping. |
keyword |
Emitted for keywords. |
label |
Emitted for labels. |
lifetime |
Emitted for lifetimes. |
parameter |
Emitted for non-self function parameters. |
property |
Emitted for struct and union fields. |
selfKeyword |
Emitted for the self function parameter and self path-specifier. |
typeParameter |
Emitted for type parameters. |
unresolvedReference |
Emitted for unresolved references, names that rust-analyzer can’t find the definition of. |
variable |
Emitted for locals, constants and statics. |
Token modifiers allow to style some elements in the source code more precisely.
Rust-analyzer currently emits the following token modifiers:
async |
Emitted for async functions and the |
attribute |
Emitted for tokens inside attributes. |
callable |
Emitted for locals whose types implements one of the |
constant |
Emitted for consts. |
consuming |
Emitted for locals that are being consumed when use in a function call. |
controlFlow |
Emitted for control-flow related tokens, this includes the |
declaration |
Emitted for names of definitions, like |
documentation |
Emitted for documentation comments. |
injected |
Emitted for doc-string injected highlighting like rust source blocks in documentation. |
intraDocLink |
Emitted for intra doc links in doc-strings. |
library |
Emitted for items that are defined outside of the current crate. |
public |
Emitted for items that are from the current crate and are |
mutable |
Emitted for mutable locals and statics. |
static |
Emitted for "static" functions, also known as functions that do not take a |
trait |
Emitted for associated trait items. |
unsafe |
Emitted for unsafe operations, like unsafe function calls, as well as the |
Source: 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 |
Source: status.rs
Shows internal statistic about memory usage of rust-analyzer.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: Status |
Source: lib.rs
Search and replace with named wildcards that will match any expression, type, path, pattern or item.
The syntax for a structural search replace command is <search_pattern> =⇒> <replace_pattern>
.
A $<name>
placeholder in the search pattern will match any AST node and $<name>
will reference it in the replacement.
Within a macro call, a placeholder will match up until whatever token follows the placeholder.
All paths in both the search pattern and the replacement template must resolve in the context
in which this command is invoked. Paths in the search pattern will then match the code if they
resolve to the same item, even if they’re written differently. For example if we invoke the
command in the module foo
with a pattern of Bar
, then code in the parent module that refers
to foo::Bar
will match.
Paths in the replacement template will be rendered appropriately for the context in which the
replacement occurs. For example if our replacement template is foo::Bar
and we match some
code in the foo
module, we’ll insert just Bar
.
Inherent method calls should generally be written in UFCS form. e.g. foo::Bar::baz($s, $a)
will
match $s.baz($a)
, provided the method call baz
resolves to the method foo::Bar::baz
. When a
placeholder is the receiver of a method call in the search pattern (e.g. $s.foo()
), but not in
the replacement template (e.g. bar($s)
), then *, & and &mut will be added as needed to mirror
whatever autoderef and autoref was happening implicitly in the matched code.
The scope of the search / replace will be restricted to the current selection if any, otherwise it will apply to the whole workspace.
Placeholders may be given constraints by writing them as ${<name>:<constraint1>:<constraint2>…}
.
Supported constraints:
Constraint | Restricts placeholder |
---|---|
kind(literal) |
Is a literal (e.g. |
not(a) |
Negates the constraint |
Available via the command rust-analyzer.ssr
.
// Using structural search replace command [foo($a, $b) ==>> ($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 |
Also available as an assist, by writing a comment containing the structural search and replace rule. You will only see the assist if the comment can be parsed as a valid structural search and replace rule.
// Place the cursor on the line below to see the assist 💡.
// foo($a, $b) ==>> ($a).foo($b)
Source: view_crate_graph.rs
Renders the currently loaded crate graph as an SVG graphic. Requires the dot
tool, which
is part of graphviz, to be installed.
Only workspace crates are included, no crates.io dependencies or sysroot crates.
Editor | Action Name |
---|---|
VS Code |
Rust Analyzer: View Crate Graph |
Source: 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 forFoo
type in the current workspace -
foo#
searches forfoo
function in the current workspace -
Foo*
searches forFoo
type among dependencies, includingstdlib
-
foo#*
searches forfoo
function among dependencies
That is, #
switches from "types" to all symbols, *
switches from the current
workspace to dependencies.
Note that filtering does not currently work in VSCode due to the editor never
sending the special symbols to the language server. Instead, you can configure
the filtering via the rust-analyzer.workspace.symbol.search.scope
and
rust-analyzer.workspace.symbol.search.kind
settings.
Editor | Shortcut |
---|---|
VS Code |
kbd:[Ctrl+T] |