diff --git a/.gitignore b/.gitignore index 68c87a6b1ed4..c6c3fb0a7b30 100644 --- a/.gitignore +++ b/.gitignore @@ -7,10 +7,9 @@ crates/*/target *.log *.iml .vscode/settings.json -generated_assists.adoc -generated_features.adoc -generated_diagnostic.adoc .DS_Store /out/ /dump.lsif .envrc +docs/book/book +docs/book/src/*/generated.md diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs index f508c42c53e4..d35af46642b4 100644 --- a/crates/ide-assists/src/handlers/auto_import.rs +++ b/crates/ide-assists/src/handlers/auto_import.rs @@ -38,7 +38,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; // use super::AssistContext; // ``` // -// .Import Granularity +// #### Import Granularity // // It is possible to configure how use-trees are merged with the `imports.granularity.group` setting. // It has the following configurations: @@ -52,7 +52,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; // // In `VS Code` the configuration for this is `rust-analyzer.imports.granularity.group`. // -// .Import Prefix +// #### Import Prefix // // The style of imports in the same crate is configurable through the `imports.prefix` setting. // It has the following configurations: @@ -66,7 +66,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; // // In `VS Code` the configuration for this is `rust-analyzer.imports.prefix`. // -// image::https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif[] +// ![Auto Import](https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif) // Assist: auto_import // diff --git a/crates/ide-assists/src/tests/sourcegen.rs b/crates/ide-assists/src/tests/sourcegen.rs index 3da90e9052f2..7cdf3e36703d 100644 --- a/crates/ide-assists/src/tests/sourcegen.rs +++ b/crates/ide-assists/src/tests/sourcegen.rs @@ -55,7 +55,7 @@ r#####" "sourcegen_assists_docs", assists.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"), ); - let dst = project_root().join("docs/user/generated_assists.adoc"); + let dst = project_root().join("docs/book/src/assists/generated.md"); fs::write(dst, contents).unwrap(); } } @@ -139,7 +139,7 @@ impl fmt::Display for Assist { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let _ = writeln!( f, - "[discrete]\n=== `{}` + "### `{}` **Source:** {}", self.id, self.location, ); @@ -152,11 +152,11 @@ impl fmt::Display for Assist { " {} -.Before +#### Before ```rust {}``` -.After +#### After ```rust {}```", section.doc, diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index d74d3b264ae5..27f9ba0c02cc 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -82,19 +82,19 @@ use crate::{ // NOTE: currently, if an assoc item comes from a trait that's not currently imported, and it also has an unresolved and/or partially-qualified path, // no imports will be proposed. // -// .Fuzzy search details +// #### Fuzzy search details // // To avoid an excessive amount of the results returned, completion input is checked for inclusion in the names only // (i.e. in `HashMap` in the `std::collections::HashMap` path). // For the same reasons, avoids searching for any path imports for inputs with their length less than 2 symbols // (but shows all associated items for any input length). // -// .Import configuration +// #### Import configuration // // It is possible to configure how use-trees are merged with the `imports.granularity.group` setting. // Mimics the corresponding behavior of the `Auto Import` feature. // -// .LSP and performance implications +// #### LSP and performance implications // // The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits` // (case-sensitive) resolve client capability in its client capabilities. @@ -102,7 +102,7 @@ use crate::{ // For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones, // which might be slow ergo the feature is automatically disabled. // -// .Feature toggle +// #### Feature toggle // // The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.autoimport.enable` flag. // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corresponding diff --git a/crates/ide-completion/src/completions/postfix/format_like.rs b/crates/ide-completion/src/completions/postfix/format_like.rs index cb242e4aa686..328c69a842c6 100644 --- a/crates/ide-completion/src/completions/postfix/format_like.rs +++ b/crates/ide-completion/src/completions/postfix/format_like.rs @@ -14,7 +14,7 @@ // ** `logw` -> `log::warn!(...)` // ** `loge` -> `log::error!(...)` // -// image::https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif[] +// ![Format String Completion](https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif) use ide_db::{ syntax_helpers::format_string_exprs::{parse_format_exprs, with_placeholders}, diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index aaf7cd7843af..93aea0f1bdcd 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -72,11 +72,13 @@ pub use crate::{ // // There also snippet completions: // -// .Expressions +// #### Expressions +// // - `pd` -> `eprintln!(" = {:?}", );` // - `ppd` -> `eprintln!(" = {:#?}", );` // -// .Items +// #### Items +// // - `tfn` -> `#[test] fn feature(){}` // - `tmod` -> // ```rust @@ -93,7 +95,7 @@ pub use crate::{ // Those are the additional completion options with automatic `use` import and options from all project importable items, // fuzzy matched against the completion input. // -// image::https://user-images.githubusercontent.com/48062697/113020667-b72ab880-917a-11eb-8778-716cf26a0eb3.gif[] +// ![Magic Completions](https://user-images.githubusercontent.com/48062697/113020667-b72ab880-917a-11eb-8778-716cf26a0eb3.gif) /// Main entry point for completion. We run completion as a two-phase process. /// diff --git a/crates/ide-completion/src/snippet.rs b/crates/ide-completion/src/snippet.rs index 50618296ee43..f009c79f00ca 100644 --- a/crates/ide-completion/src/snippet.rs +++ b/crates/ide-completion/src/snippet.rs @@ -8,8 +8,7 @@ // // A custom snippet can be defined by adding it to the `rust-analyzer.completion.snippets.custom` object respectively. // -// [source,json] -// ---- +// ```json // { // "rust-analyzer.completion.snippets.custom": { // "thread spawn": { @@ -25,7 +24,7 @@ // } // } // } -// ---- +// ``` // // In the example above: // @@ -39,6 +38,7 @@ // * `description` is an optional description of the snippet, if unset the snippet name will be used. // // * `requires` is an optional list of item paths that have to be resolvable in the current crate where the completion is rendered. + // On failure of resolution the snippet won't be applicable, otherwise the snippet will insert an import for the items on insertion if // the items aren't yet in scope. // @@ -55,8 +55,8 @@ // // For the VSCode editor, rust-analyzer also ships with a small set of defaults which can be removed // by overwriting the settings object mentioned above, the defaults are: -// [source,json] -// ---- +// +// ```json // { // "Arc::new": { // "postfix": "arc", @@ -98,7 +98,7 @@ // "scope": "expr" // } // } -// ---- +// ```` use ide_db::imports::import_assets::LocatedImport; use itertools::Itertools; diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs index a0b05c87ae73..a8bce9bc5f7b 100644 --- a/crates/ide-db/src/apply_change.rs +++ b/crates/ide-db/src/apply_change.rs @@ -44,12 +44,11 @@ impl RootDatabase { // // Clears rust-analyzer's internal database and prints memory usage statistics. // - // |=== - // | Editor | Action Name - // + // | Editor | Action Name | + // |---------|-------------| // | VS Code | **rust-analyzer: Memory Usage (Clears Database)** - // |=== - // image::https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif[] + + // ![Memory Usage](https://user-images.githubusercontent.com/48062697/113065592-08559f00-91b1-11eb-8c96-64b88068ec02.gif) pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes, usize)> { let mut acc: Vec<(String, Bytes, usize)> = vec![]; diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs index 3e89159c2c6e..97eabe8e31e4 100644 --- a/crates/ide-db/src/symbol_index.rs +++ b/crates/ide-db/src/symbol_index.rs @@ -199,11 +199,9 @@ impl std::ops::Deref for Snap { // 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] -// |=== +// | Editor | Shortcut | +// |---------|-----------| +// | VS Code | Ctrl+T pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { let _p = profile::span("world_symbols").detail(|| query.query.clone()); diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 85dbb7e6f263..55d5c99d4845 100644 --- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -12,7 +12,7 @@ use crate::{ // Diagnostic: incorrect-ident-case // -// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention]. +// This diagnostic is triggered if an item name doesn't follow [Rust naming convention](https://doc.rust-lang.org/1.0.0/style/style/naming/README.html). pub(crate) fn incorrect_case(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Diagnostic { let code = match d.expected_case { CaseType::LowerSnakeCase => DiagnosticCode::RustcLint("non_snake_case"), diff --git a/crates/ide-diagnostics/src/tests/sourcegen.rs b/crates/ide-diagnostics/src/tests/sourcegen.rs index 9e7fcfc590b7..df41c99ce1be 100644 --- a/crates/ide-diagnostics/src/tests/sourcegen.rs +++ b/crates/ide-diagnostics/src/tests/sourcegen.rs @@ -10,7 +10,7 @@ fn sourcegen_diagnostic_docs() { let contents = diagnostics.into_iter().map(|it| it.to_string()).collect::>().join("\n\n"); let contents = sourcegen::add_preamble("sourcegen_diagnostic_docs", contents); - let dst = project_root().join("docs/user/generated_diagnostic.adoc"); + let dst = project_root().join("docs/book/src/diagnostics/generated.md"); fs::write(dst, contents).unwrap(); } @@ -68,6 +68,6 @@ fn is_valid_diagnostic_name(diagnostic: &str) -> Result<(), String> { impl fmt::Display for Diagnostic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!(f, "=== {}\n**Source:** {}\n{}", self.id, self.location, self.doc) + writeln!(f, "#### {}\n\nSource: {}\n\n{}\n\n", self.id, self.location, self.doc) } } diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs index 66832a0bee49..92c030dca0a9 100644 --- a/crates/ide-ssr/src/lib.rs +++ b/crates/ide-ssr/src/lib.rs @@ -35,12 +35,10 @@ // // Supported constraints: // -// |=== -// | Constraint | Restricts placeholder -// -// | kind(literal) | Is a literal (e.g. `42` or `"forty two"`) -// | not(a) | Negates the constraint `a` -// |=== +// | Constraint | Restricts placeholder | +// |---------------|------------------------| +// | kind(literal) | Is a literal (e.g. `42` or `"forty two"`) | +// | not(a) | Negates the constraint `a` | // // Available via the command `rust-analyzer.ssr`. // @@ -54,11 +52,9 @@ // String::from((y + 5).foo(z)) // ``` // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: Structural Search Replace** -// |=== +// | 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 diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs index fb79b5dc211a..ea55f17e6a25 100644 --- a/crates/ide/src/annotations.rs +++ b/crates/ide/src/annotations.rs @@ -22,7 +22,7 @@ mod fn_references; // Provides user with annotations above items for looking up references or impl blocks // and running/debugging binaries. // -// image::https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png[] +// ![Annotations](https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png) #[derive(Debug)] pub struct Annotation { pub range: TextRange, diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index ac15b6aba618..6bb0c955dc67 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -125,11 +125,9 @@ pub(crate) fn remove_links(markdown: &str) -> String { // The simplest way to use this feature is via the context menu. Right-click on // the selected item. The context menu opens. Select **Open Docs**. // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: Open Docs** -// |=== +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Open Docs** | pub(crate) fn external_docs( db: &RootDatabase, FilePosition { file_id, offset }: FilePosition, diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 322077456775..e8e61b04e81c 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -16,13 +16,11 @@ pub struct ExpandedMacro { // // Shows the full macro expansion of the macro at the current caret position. // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Expand macro recursively** | // -// | VS Code | **rust-analyzer: Expand macro recursively at caret** -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[] +// ![Expand Macro Recursively](/img/features/expand_macro_recursively.gif) pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option { let sema = Semantics::new(db); let file = sema.parse(position.file_id); diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs index 3d89599c5832..edd36439cdfd 100644 --- a/crates/ide/src/extend_selection.rs +++ b/crates/ide/src/extend_selection.rs @@ -17,13 +17,11 @@ use crate::FileRange; // Extends or shrinks the current selection to the encompassing syntactic construct // (expression, statement, item, module, etc). It works with multiple cursors. // -// |=== -// | Editor | Shortcut +// | Editor | Shortcut | +// |---------|----------| +// | VS Code | Alt+Shift+→, Alt+Shift+← | // -// | VS Code | kbd:[Alt+Shift+→], kbd:[Alt+Shift+←] -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif[] +// ![Expand and Shrink Selection](https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif) pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { let sema = Semantics::new(db); let src = sema.parse(frange.file_id); diff --git a/crates/ide/src/fetch_crates.rs b/crates/ide/src/fetch_crates.rs index 46ee671defbc..b7797d1d6461 100644 --- a/crates/ide/src/fetch_crates.rs +++ b/crates/ide/src/fetch_crates.rs @@ -14,13 +14,11 @@ pub struct CrateInfo { // // Shows a view tree with all the dependencies of this project // -// |=== -// | Editor | Panel Name +// | Editor | Panel Name | +// |---------|------------| +// | VS Code | **Rust Dependencies** | // -// | VS Code | **Rust Dependencies** -// |=== -// -// image::https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png[] +// ![Show Dependency Tree](https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png) pub(crate) fn fetch_crates(db: &RootDatabase) -> FxIndexSet { let crate_graph = db.crate_graph(); crate_graph diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs index b278924721c0..4a283fbc02a8 100644 --- a/crates/ide/src/file_structure.rs +++ b/crates/ide/src/file_structure.rs @@ -30,14 +30,11 @@ pub enum StructureNodeKind { // * draw breadcrumbs to describe the context around the cursor // * draw outline of the file // -// |=== -// | Editor | Shortcut +// | Editor | Shortcut | +// |---------|----------| +// | VS Code | Ctrl+Shift+O | // -// | VS Code | kbd:[Ctrl+Shift+O] -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif[] - +// ![File Structure](https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif) pub(crate) fn file_structure(file: &SourceFile) -> Vec { let mut res = Vec::new(); let mut stack = Vec::new(); diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index e09b9f391482..81159b07842b 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -20,13 +20,11 @@ use syntax::{ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T}; // // For outline modules, this will navigate to the source file of the module. // -// |=== -// | Editor | Shortcut +// | Editor | Shortcut | +// |---------|----------| +// | VS Code | F12 | // -// | VS Code | kbd:[F12] -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[] +// ![Go to Definition](https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif) pub(crate) fn goto_definition( db: &RootDatabase, FilePosition { file_id, offset }: FilePosition, diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 544c6b42317e..d8a1e89895cc 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -13,13 +13,11 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav}; // // Navigates to the impl blocks of types. // -// |=== -// | Editor | Shortcut +// | Editor | Shortcut | +// |---------|----------| +// | VS Code | Ctrl+F12 // -// | VS Code | kbd:[Ctrl+F12] -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif[] +// ![Go to Implementation](https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif) pub(crate) fn goto_implementation( db: &RootDatabase, FilePosition { file_id, offset }: FilePosition, diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index 955923d76910..10ec047bcbcf 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs @@ -7,13 +7,11 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav}; // // Navigates to the type of an identifier. // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **Go to Type Definition** | // -// | VS Code | **Go to Type Definition** -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif[] +// ![Go to Type Definition](https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif) pub(crate) fn goto_type_definition( db: &RootDatabase, FilePosition { file_id, offset }: FilePosition, diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index e0b64fe7988e..575dced2995e 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -99,7 +99,7 @@ pub struct HoverResult { // 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. // -// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif[] +// ![Hover](https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif) pub(crate) fn hover( db: &RootDatabase, frange @ FileRange { file_id, range }: FileRange, diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index a5d070fe7673..0a4d8b800cd0 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -435,7 +435,7 @@ fn ty_to_text_edit( // * elided lifetimes // * compiler inserted reborrows // -// image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[] +// ![Hover](https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png) pub(crate) fn inlay_hints( db: &RootDatabase, file_id: FileId, diff --git a/crates/ide/src/interpret_function.rs b/crates/ide/src/interpret_function.rs index d06ffd535758..0d4c196e46b0 100644 --- a/crates/ide/src/interpret_function.rs +++ b/crates/ide/src/interpret_function.rs @@ -8,11 +8,9 @@ use syntax::{algo::find_node_at_offset, ast, AstNode}; // Feature: Interpret Function // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: Interpret Function** -// |=== +// | Editor | Action Name | +// |---------|--------------| +// | VS Code | **rust-analyzer: Interpret Function** | pub(crate) fn interpret_function(db: &RootDatabase, position: FilePosition) -> String { let start_time = Instant::now(); let mut result = find_and_interpret(db, position) diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs index 1cfde2362455..bac604c04ce8 100644 --- a/crates/ide/src/join_lines.rs +++ b/crates/ide/src/join_lines.rs @@ -21,17 +21,13 @@ pub struct JoinLinesConfig { // // Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces. // -// See -// https://user-images.githubusercontent.com/1711539/124515923-4504e800-dde9-11eb-8d58-d97945a1a785.gif[this gif] -// for the cases handled specially by joined lines. +// See [this gif](img/features/join_lines-1.gif) for the cases handled specially by joined lines. // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Join lines** | // -// | VS Code | **rust-analyzer: Join lines** -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif[] +// ![Join Lines](https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif) pub(crate) fn join_lines( config: &JoinLinesConfig, file: &SourceFile, diff --git a/crates/ide/src/matching_brace.rs b/crates/ide/src/matching_brace.rs index 6e8a6d020cc7..22b12d3163d7 100644 --- a/crates/ide/src/matching_brace.rs +++ b/crates/ide/src/matching_brace.rs @@ -9,13 +9,11 @@ use syntax::{ // 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 +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Find matching brace** | // -// | VS Code | **rust-analyzer: Find matching brace** -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif[] +// ![Matching Brace](https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif) pub(crate) fn matching_brace(file: &SourceFile, offset: TextSize) -> Option { const BRACES: &[SyntaxKind] = &[T!['{'], T!['}'], T!['['], T![']'], T!['('], T![')'], T![<], T![>], T![|], T![|]]; diff --git a/crates/ide/src/move_item.rs b/crates/ide/src/move_item.rs index b955ea99f0c0..6532ef594dcf 100644 --- a/crates/ide/src/move_item.rs +++ b/crates/ide/src/move_item.rs @@ -16,14 +16,12 @@ pub enum Direction { // // Move item under cursor or selection up and down. // -// |=== -// | Editor | Action Name -// +// | Editor | Action Name | +// |---------|-------------| // | VS Code | **rust-analyzer: Move item up** // | VS Code | **rust-analyzer: Move item down** -// |=== // -// image::https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif[] +// ![Move Item](https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif) pub(crate) fn move_item( db: &RootDatabase, range: FileRange, diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs index 506f9452cf19..a0d0e7b0f767 100644 --- a/crates/ide/src/parent_module.rs +++ b/crates/ide/src/parent_module.rs @@ -15,13 +15,11 @@ use crate::NavigationTarget; // // Navigates to the parent module of the current module. // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Locate parent module** | // -// | VS Code | **rust-analyzer: Locate parent module** -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif[] +// ![Parent Module](https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif) /// This returns `Vec` because a module may be included from several places. pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec { diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index f387bbf6b014..fd39d5980b61 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -44,13 +44,11 @@ pub struct Declaration { // // Shows all references of the item at the cursor location // -// |=== -// | Editor | Shortcut +// | Editor | Shortcut | +// |---------|----------| +// | VS Code | Shift+Alt+F12 | // -// | VS Code | kbd:[Shift+Alt+F12] -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif[] +// ![Find All References](https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif) pub(crate) fn find_all_refs( sema: &Semantics<'_, RootDatabase>, position: FilePosition, diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index ac9df5ed6d1f..9a7a7671f369 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -74,13 +74,11 @@ pub(crate) fn prepare_rename( // // Renames the item below the cursor and all of its references // -// |=== -// | Editor | Shortcut +// | Editor | Shortcut | +// |---------|----------| +// | VS Code | F2 | // -// | VS Code | kbd:[F2] -// |=== -// -// image::https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif[] +// ![Rename](https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif) pub(crate) fn rename( db: &RootDatabase, position: FilePosition, diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 07cdddd15f82..b4c1af32394b 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -114,12 +114,11 @@ impl Runnable { // location**. Super useful for repeatedly running just a single test. Do bind this // to a shortcut! // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Run** | // -// | VS Code | **rust-analyzer: Run** -// |=== -// image::https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif[] +// ![Run](https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif) pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec { let sema = Semantics::new(db); @@ -199,11 +198,9 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec { // 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** -// |=== +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Peek Related Tests** | pub(crate) fn related_tests( db: &RootDatabase, position: FilePosition, diff --git a/crates/ide/src/shuffle_crate_graph.rs b/crates/ide/src/shuffle_crate_graph.rs index f85700daf1f7..e3fd0a44831c 100644 --- a/crates/ide/src/shuffle_crate_graph.rs +++ b/crates/ide/src/shuffle_crate_graph.rs @@ -8,11 +8,9 @@ use triomphe::Arc; // // Randomizes all crate IDs in the crate graph, for debugging. // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: Shuffle Crate Graph** -// |=== +// | Editor | Action Name | +// |---------|--------------| +// | VS Code | **rust-analyzer: Shuffle Crate Graph** | pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) { let crate_graph = db.crate_graph(); let proc_macros = db.proc_macros(); diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs index c9ee460a1c26..8a15ba4e021a 100644 --- a/crates/ide/src/status.rs +++ b/crates/ide/src/status.rs @@ -29,12 +29,11 @@ use triomphe::Arc; // // Shows internal statistic about memory usage of rust-analyzer. // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Status** | // -// | VS Code | **rust-analyzer: Status** -// |=== -// image::https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif[] +// ![Status](https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif) pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { let mut buf = String::new(); diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index dd72484b3807..03576a392bd5 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -73,113 +73,118 @@ pub struct HighlightConfig { // We also give special modifier for `mut` and `&mut` local variables. // // -// .Token Tags +// #### Token Tags // // Rust-analyzer currently emits the following token tags: // // - For items: -// + -// [horizontal] -// attribute:: Emitted for attribute macros. -// enum:: Emitted for enums. -// function:: Emitted for free-standing functions. -// derive:: Emitted for derive macros. -// macro:: Emitted for function-like 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. +// +// | | | +// |-----------|--------------------------------| +// | attribute | Emitted for attribute macros. | +// |enum| Emitted for enums. | +// |function| Emitted for free-standing functions. | +// |derive| Emitted for derive macros. | +// |macro| Emitted for function-like 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: -// + -// [horizontal] -// boolean:: Emitted for the boolean literals `true` and `false`. -// 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 `{:?}` in `format!`-like macros. +// +// | | | +// |-----------|--------------------------------| +// | boolean| Emitted for the boolean literals `true` and `false`.| +// | 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 `{:?}` in `format!`-like macros.| // // - For operators: -// + -// [horizontal] -// 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 `||`, `&&`, `!`. +// +// | | | +// |-----------|--------------------------------| +// |operator| Emitted for general operators.| +// |arithmetic| Emitted for the arithmetic operators `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=`.| +// |bitwise| Emitted for the bitwise operators `|`, `&`, `!`, `^`, `|=`, `&=`, `^=`.| +// |comparison| Emitted for the comparison oerators `>`, `<`, `==`, `>=`, `<=`, `!=`.| +// |logical| Emitted for the logical operatos `||`, `&&`, `!`.| // // - For punctuation: -// + -// [horizontal] -// punctuation:: Emitted for general punctuation. -// attributeBracket:: Emitted for attribute invocation brackets, that is the `#[` and `]` tokens. -// 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. -// macroBang:: Emitted for the `!` token in macro calls. // -// //- +// | | | +// |-----------|--------------------------------| +// |punctuation| Emitted for general punctuation.| +// |attributeBracket| Emitted for attribute invocation brackets, that is the `#[` and `]` tokens.| +// |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.| +// |macroBang| Emitted for the `!` token in macro calls.| // -// [horizontal] -// builtinAttribute:: Emitted for names to builtin attributes in attribute path, the `repr` in `#[repr(u8)]` for example. -// builtinType:: Emitted for builtin types like `u32`, `str` and `f32`. -// comment:: Emitted for comments. -// constParameter:: Emitted for const parameters. -// deriveHelper:: Emitted for derive helper attributes. -// 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. -// selfTypeKeyword:: Emitted for the Self type parameter. -// toolModule:: Emitted for tool modules. -// 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. +//- // +// | | | +// |-----------|--------------------------------| +// |builtinAttribute| Emitted for names to builtin attributes in attribute path, the `repr` in `#[repr(u8)]` for example.| +// |builtinType| Emitted for builtin types like `u32`, `str` and `f32`.| +// |comment| Emitted for comments.| +// |constParameter| Emitted for const parameters.| +// |deriveHelper| Emitted for derive helper attributes.| +// |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.| +// |selfTypeKeyword| Emitted for the Self type parameter.| +// |toolModule| Emitted for tool modules.| +// |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 +// +// #### Token Modifiers // // Token modifiers allow to style some elements in the source code more precisely. // // Rust-analyzer currently emits the following token modifiers: // -// [horizontal] -// async:: Emitted for async functions and the `async` and `await` keywords. -// attribute:: Emitted for tokens inside attributes. -// callable:: Emitted for locals whose types implements one of the `Fn*` traits. -// 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 `?` operator. -// crateRoot:: Emitted for crate names, like `serde` and `crate`. -// declaration:: Emitted for names of definitions, like `foo` in `fn foo() {}`. -// defaultLibrary:: Emitted for items from built-in crates (std, core, alloc, test and proc_macro). -// 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. -// macro:: Emitted for tokens inside macro calls. -// mutable:: Emitted for mutable locals and statics as well as functions taking `&mut self`. -// public:: Emitted for items that are from the current crate and are `pub`. -// reference:: Emitted for locals behind a reference and functions taking `self` by reference. -// static:: Emitted for "static" functions, also known as functions that do not take a `self` param, as well as statics and consts. -// trait:: Emitted for associated trait items. -// unsafe:: Emitted for unsafe operations, like unsafe function calls, as well as the `unsafe` token. -// +// | | | +// |-----------|--------------------------------| +// |async| Emitted for async functions and the `async` and `await` keywords.| +// |attribute| Emitted for tokens inside attributes.| +// |callable| Emitted for locals whose types implements one of the `Fn*` taits.| +// |constant| Emitted for const.| +// |consuming| Emitted for locals that are being consumed when use in a fuction call.| +// |controlFlow| Emitted for control-flow related tokens, this includes th `?` operator.| +// |crateRoot| Emitted for crate names, like `serde` and `crate.| +// |declaration| Emitted for names of definitions, like `foo` in `fn foo(){}`.| +// |defaultLibrary| Emitted for items from built-in crates (std, core, allc, test and proc_macro).| +// |documentation| Emitted for documentation comment.| +// |injected| Emitted for doc-string injected highlighting like rust sourc blocks in documentation.| +// |intraDocLink| Emitted for intra doc links in doc-string.| +// |library| Emitted for items that are defined outside of the current crae.| +// |macro| Emitted for tokens inside macro call.| +// |mutable| Emitted for mutable locals and statics as well as functions tking `&mut self`.| +// |public| Emitted for items that are from the current crate and are `pub.| +// |reference| Emitted for locals behind a reference and functions taking self` by reference.| +// |static| Emitted for "static" functions, also known as functions that d not take a `self` param, as well as statics and consts.| +// |trait| Emitted for associated trait item.| +// |unsafe| Emitted for unsafe operations, like unsafe function calls, as ell as the `unsafe` token.| // -// image::https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png[] -// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[] +// ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png) +// ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png) pub(crate) fn highlight( db: &RootDatabase, config: HighlightConfig, diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs index df1971242657..9c8e6557b2e2 100644 --- a/crates/ide/src/syntax_tree.rs +++ b/crates/ide/src/syntax_tree.rs @@ -11,12 +11,11 @@ use syntax::{ // Shows the parse tree of the current file. It exists mostly for debugging // rust-analyzer itself. // -// |=== -// | Editor | Action Name +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Show Syntax Tree** | // -// | VS Code | **rust-analyzer: Show Syntax Tree** -// |=== -// image::https://user-images.githubusercontent.com/48062697/113065586-068bdb80-91b1-11eb-9507-fee67f9f45a0.gif[] +// ![Show Syntax Tree](https://user-images.githubusercontent.com/48062697/113065586-068bdb80-91b1-11eb-9507-fee67f9f45a0.gif) pub(crate) fn syntax_tree( db: &RootDatabase, file_id: FileId, diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index d21850bcff3e..c90ba95cb4b1 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs @@ -53,13 +53,12 @@ struct ExtendedTextEdit { // VS Code:: // // Add the following to `settings.json`: -// [source,json] -// ---- +// ```json // "editor.formatOnType": true, -// ---- +// ``` // -// image::https://user-images.githubusercontent.com/48062697/113166163-69758500-923a-11eb-81ee-eb33ec380399.gif[] -// image::https://user-images.githubusercontent.com/48062697/113171066-105c2000-923f-11eb-87ab-f4a263346567.gif[] +// ![On Typing Assists](https://user-images.githubusercontent.com/48062697/113166163-69758500-923a-11eb-81ee-eb33ec380399.gif) +// ![On Typing Assists](https://user-images.githubusercontent.com/48062697/113171066-105c2000-923f-11eb-87ab-f4a263346567.gif) pub(crate) fn on_char_typed( db: &RootDatabase, position: FilePosition, diff --git a/crates/ide/src/typing/on_enter.rs b/crates/ide/src/typing/on_enter.rs index 298482f2ab5c..4bffbf383519 100644 --- a/crates/ide/src/typing/on_enter.rs +++ b/crates/ide/src/typing/on_enter.rs @@ -17,10 +17,10 @@ use text_edit::TextEdit; // // 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 +// - Enter inside triple-slash comments automatically inserts `///` +// - Enter in the middle or after a trailing space in `//` inserts `//` +// - Enter inside `//!` doc comments automatically inserts `//!` +// - Enter after `{` indents contents and closing `}` of single-line block // // This action needs to be assigned to shortcut explicitly. // @@ -31,26 +31,24 @@ use text_edit::TextEdit; // VS Code:: // // Add the following to `keybindings.json`: -// [source,json] -// ---- +// ```json // { // "key": "Enter", // "command": "rust-analyzer.onEnter", // "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust" // } -// ---- +// ```` // // When using the Vim plugin: -// [source,json] -// ---- +// ```json // { // "key": "Enter", // "command": "rust-analyzer.onEnter", // "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust && vim.mode == 'Insert'" // } -// ---- +// ```` // -// image::https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif[] +// ![On Enter](https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif) pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option { let parse = db.parse(position.file_id); let file = parse.tree(); diff --git a/crates/ide/src/view_crate_graph.rs b/crates/ide/src/view_crate_graph.rs index 8c84461f659f..463085078b79 100644 --- a/crates/ide/src/view_crate_graph.rs +++ b/crates/ide/src/view_crate_graph.rs @@ -12,11 +12,9 @@ use triomphe::Arc; // // Only workspace crates are included, no crates.io dependencies or sysroot crates. // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: View Crate Graph** -// |=== +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: View Crate Graph** | pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result { let crate_graph = db.crate_graph(); let crates_to_render = crate_graph diff --git a/crates/ide/src/view_hir.rs b/crates/ide/src/view_hir.rs index d2bbbf6d26ab..9083735d605e 100644 --- a/crates/ide/src/view_hir.rs +++ b/crates/ide/src/view_hir.rs @@ -5,12 +5,11 @@ use syntax::{algo::find_node_at_offset, ast, AstNode}; // Feature: View Hir // -// |=== -// | Editor | Action Name -// +// | Editor | Action Name | +// |---------|--------------| // | VS Code | **rust-analyzer: View Hir** -// |=== -// image::https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif[] +// +// ![View Hir](https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif) pub(crate) fn view_hir(db: &RootDatabase, position: FilePosition) -> String { body_hir(db, position).unwrap_or_else(|| "Not inside a function body".to_string()) } diff --git a/crates/ide/src/view_item_tree.rs b/crates/ide/src/view_item_tree.rs index e072df430fc0..637cba9e639f 100644 --- a/crates/ide/src/view_item_tree.rs +++ b/crates/ide/src/view_item_tree.rs @@ -6,11 +6,9 @@ use ide_db::RootDatabase; // // Displays the ItemTree of the currently open file, for debugging. // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: Debug ItemTree** -// |=== +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: Debug ItemTree** | pub(crate) fn view_item_tree(db: &RootDatabase, file_id: FileId) -> String { db.file_item_tree(file_id.into()).pretty_print(db) } diff --git a/crates/ide/src/view_memory_layout.rs b/crates/ide/src/view_memory_layout.rs index 3802978f4941..a3eb4d2de7b7 100644 --- a/crates/ide/src/view_memory_layout.rs +++ b/crates/ide/src/view_memory_layout.rs @@ -78,11 +78,9 @@ impl FieldOrTupleIdx { // // Displays the recursive memory layout of a datatype. // -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: View Memory Layout** -// |=== +// | Editor | Action Name | +// |---------|-------------| +// | VS Code | **rust-analyzer: View Memory Layout** | pub(crate) fn view_memory_layout( db: &RootDatabase, position: FilePosition, diff --git a/crates/ide/src/view_mir.rs b/crates/ide/src/view_mir.rs index a36aba58bc0e..eecd5b9c63ec 100644 --- a/crates/ide/src/view_mir.rs +++ b/crates/ide/src/view_mir.rs @@ -5,11 +5,9 @@ use syntax::{algo::find_node_at_offset, ast, AstNode}; // Feature: View Mir // -// |=== -// | Editor | Action Name -// +// | Editor | Action Name | +// |---------|-------------| // | VS Code | **rust-analyzer: View Mir** -// |=== pub(crate) fn view_mir(db: &RootDatabase, position: FilePosition) -> String { body_mir(db, position).unwrap_or_else(|| "Not inside a function body".to_string()) } diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index f28f6ffb8748..f04572190315 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -347,7 +347,7 @@ config_data! { imports_granularity_enforce: bool = "false", /// How imports should be grouped into use statements. imports_granularity_group: ImportGranularityDef = "\"crate\"", - /// Group inserted imports by the https://rust-analyzer.github.io/manual.html#auto-import[following order]. Groups are separated by newlines. + /// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines. imports_group_enable: bool = "true", /// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`. imports_merge_glob: bool = "true", @@ -2525,20 +2525,9 @@ fn manual(fields: &[(&'static str, &'static str, &[&str], &str)]) -> String { let name = format!("rust-analyzer.{}", field.replace('_', ".")); let doc = doc_comment_to_string(doc); if default.contains('\n') { - format!( - r#"[[{name}]]{name}:: -+ --- -Default: ----- -{default} ----- -{doc} --- -"# - ) + format!(" **{name}**\n\nDefault:\n\n```{default}\n\n```\n\n {doc}\n\n ") } else { - format!("[[{name}]]{name} (default: `{default}`)::\n+\n--\n{doc}--\n") + format!("**{name}** (default: {default})\n\n {doc}\n\n") } }) .collect::() @@ -2612,7 +2601,7 @@ mod tests { #[test] fn generate_config_documentation() { - let docs_path = project_root().join("docs/user/generated_config.adoc"); + let docs_path = project_root().join("docs/book/src/configuration/generated.md"); let expected = ConfigData::manual(); ensure_file_contents(&docs_path, &expected); } diff --git a/crates/rust-analyzer/tests/slow-tests/sourcegen.rs b/crates/rust-analyzer/tests/slow-tests/sourcegen.rs index 2eafb0da6921..d165a000c355 100644 --- a/crates/rust-analyzer/tests/slow-tests/sourcegen.rs +++ b/crates/rust-analyzer/tests/slow-tests/sourcegen.rs @@ -13,7 +13,7 @@ fn sourcegen_feature_docs() { ", contents.trim() ); - let dst = sourcegen::project_root().join("docs/user/generated_features.adoc"); + let dst = sourcegen::project_root().join("docs/book/src/features/generated.md"); fs::write(dst, contents).unwrap(); } @@ -75,6 +75,6 @@ fn is_valid_feature_name(feature: &str) -> Result<(), String> { impl fmt::Display for Feature { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!(f, "=== {}\n**Source:** {}\n{}", self.id, self.location, self.doc) + writeln!(f, "### {}\n**Source:** {}\n{}", self.id, self.location, self.doc) } } diff --git a/crates/sourcegen/src/lib.rs b/crates/sourcegen/src/lib.rs index 1514c6c7d4c1..f855727d3047 100644 --- a/crates/sourcegen/src/lib.rs +++ b/crates/sourcegen/src/lib.rs @@ -122,13 +122,7 @@ impl fmt::Display for Location { let path = self.file.strip_prefix(project_root()).unwrap().display().to_string(); let path = path.replace('\\', "/"); let name = self.file.file_name().unwrap(); - write!( - f, - "https://github.com/rust-lang/rust-analyzer/blob/master/{}#L{}[{}]", - path, - self.line, - name.to_str().unwrap() - ) + write!(f, " [{}]({}#{}) ", name.to_str().unwrap(), path, self.line) } } diff --git a/docs/book/.gitignore b/docs/book/.gitignore new file mode 100644 index 000000000000..7585238efedf --- /dev/null +++ b/docs/book/.gitignore @@ -0,0 +1 @@ +book diff --git a/docs/book/Makefile b/docs/book/Makefile new file mode 100644 index 000000000000..e8775a9d5273 --- /dev/null +++ b/docs/book/Makefile @@ -0,0 +1,11 @@ +.PHONY: deploy +deploy: book + @echo "====> deploying to github" + git worktree add /tmp/book gh-pages + mdbook build + rm -rf /tmp/book/* + cp -rp book/* /tmp/book/ + cd /tmp/book && \ + git add -A && \ + git commit -m "deployed on $(shell date) by ${USER}" && \ + git push origin gh-pages \ No newline at end of file diff --git a/docs/book/README.md b/docs/book/README.md new file mode 100644 index 000000000000..57e40b9af2b4 --- /dev/null +++ b/docs/book/README.md @@ -0,0 +1,26 @@ +# rust-analyzer documentation + +The rust analyzer manual uses [mdbook](https://rust-lang.github.io/mdBook/). + +## Quick start + +To run the documentation site locally: + +```shell +cargo install mdbook +cd docs/book +mdbook serve +# make changes to documentation files in doc/book/src +# ... +``` + +mdbook will rebuild the documentation as changes are made. + +## Making updates + +While not required, installing the mdbook binary can be helfpul in order to see the changes. Start with the mdbook [User Guide](https://rust-lang.github.io/mdBook/guide/installation.html) to familiarize +yourself with the tool. + +## Generated documentation + +Four sections are generated dynamically: assists, configuration, diagnostics and features. Their content is found in the `generated` directory and are included in the book via mdbook's [include](https://rust-lang.github.io/mdBook/format/mdbook.html#including-files) functionality. diff --git a/docs/book/book.toml b/docs/book/book.toml new file mode 100644 index 000000000000..2aec8c39c947 --- /dev/null +++ b/docs/book/book.toml @@ -0,0 +1,41 @@ +[book] +authors = ["The rust-analyzer authors"] +language = "en" +multilingual = false +src = "src" +title = "rust-analyzer" + +[rust] +edition = "2021" + +[output.html] +edit-url-template = "https://github.com/rust-analyzer/rust-analyzer/edit/master/manual/{path}" +git-repository-url = "https://github.com/rust-analyzer/rust-analyzer/tree/master/manual" +mathjax-support = true +site-url = "/rust-analyzer/" + +[output.html.playground] +editable = true +runnable = false +line-numbers = true + +[output.html.search] +boost-hierarchy = 2 +boost-paragraph = 1 +boost-title = 2 +expand = true +heading-split-level = 2 +limit-results = 20 +use-boolean-and = true + +[ouput.html.redirect] +"/manual.html" = "/index.html" + +[output.html.fold] +enable = true +level = 3 + +[preprocessor.toc] +command = "mdbook-toc" +renderer = ["html"] +max-level = 3 diff --git a/docs/book/src/README.md b/docs/book/src/README.md new file mode 100644 index 000000000000..0fa089897fc6 --- /dev/null +++ b/docs/book/src/README.md @@ -0,0 +1,22 @@ +# rust-analyzer + +At its core, rust-analyzer is a **library** for semantic analysis of +Rust code as it changes over time. This manual focuses on a specific +usage of the library — running it as part of a server that implements +the [Language Server +Protocol](https://microsoft.github.io/language-server-protocol/) (LSP). +The LSP allows various code editors, like VS Code, Emacs or Vim, to +implement semantic features like completion or goto definition by +talking to an external language server process. + +To improve this document, send a pull request: +[https://github.com/rust-analyzer/…​/manual.adoc](https://github.com/rust-lang/rust-analyzer/blob/master/docs/user/manual.adoc) + +The manual is written in [AsciiDoc](https://asciidoc.org) and includes +some extra files which are generated from the source code. Run +`cargo test` and `cargo test -p xtask` to create these and then +`asciidoctor manual.adoc` to create an HTML copy. + +If you have questions about using rust-analyzer, please ask them in the +[“IDEs and Editors”](https://users.rust-lang.org/c/ide/14) topic of Rust +users forum. diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md new file mode 100644 index 000000000000..ea408d5d1ed9 --- /dev/null +++ b/docs/book/src/SUMMARY.md @@ -0,0 +1,13 @@ +# Summary + +- [Introduction](README.md) +- [Installation](installation/README.md) +- [Troubleshooting](troubleshooting/README.md) +- [Configuration](configuration/README.md) +- [Non-Cargo Based Projects](non_cargo_based_projects/README.md) +- [Security](security/README.md) +- [Privacy](privacy/README.md) +- [Features](features/README.md) +- [Assists (Code Actions)](assists/README.md) +- [Diagnostics](diagnostics/README.md) +- [Editor Features](editor_features/README.md) diff --git a/docs/book/src/assists/README.md b/docs/book/src/assists/README.md new file mode 100644 index 000000000000..f2ed48522ebf --- /dev/null +++ b/docs/book/src/assists/README.md @@ -0,0 +1,8 @@ +# Assists + +Assists, or code actions, are small local refactorings, available in a +particular context. They are usually triggered by a shortcut or by +clicking a light bulb icon in the editor. Cursor position or selection +is signified by `┃` character. + +{{#include generated.md:2:}} diff --git a/docs/book/src/assists/generated.md b/docs/book/src/assists/generated.md new file mode 100644 index 000000000000..ff1f320daa2c --- /dev/null +++ b/docs/book/src/assists/generated.md @@ -0,0 +1,3427 @@ +//! Generated by `sourcegen_assists_docs`, do not edit by hand. + +### `add_braces` +**Source:** [add_braces.rs](crates/ide-assists/src/handlers/add_braces.rs#8) + +Adds braces to lambda and match arm expressions. + +#### Before +```rust +fn foo(n: i32) -> i32 { + match n { + 1 =>┃ n + 1, + _ => 0 + } +} +``` + +#### After +```rust +fn foo(n: i32) -> i32 { + match n { + 1 => { + n + 1 + }, + _ => 0 + } +} +``` + + +### `add_explicit_type` +**Source:** [add_explicit_type.rs](crates/ide-assists/src/handlers/add_explicit_type.rs#7) + +Specify type for a let binding. + +#### Before +```rust +fn main() { + let x┃ = 92; +} +``` + +#### After +```rust +fn main() { + let x: i32 = 92; +} +``` + + +### `add_hash` +**Source:** [raw_string.rs](crates/ide-assists/src/handlers/raw_string.rs#89) + +Adds a hash to a raw string literal. + +#### Before +```rust +fn main() { + r#"Hello,┃ World!"#; +} +``` + +#### After +```rust +fn main() { + r##"Hello, World!"##; +} +``` + + +### `add_impl_default_members` +**Source:** [add_missing_impl_members.rs](crates/ide-assists/src/handlers/add_missing_impl_members.rs#55) + +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) {} + + ┃fn bar(&self) {} +} +``` + + +### `add_impl_missing_members` +**Source:** [add_missing_impl_members.rs](crates/ide-assists/src/handlers/add_missing_impl_members.rs#13) + +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 () { + ┃type X; + + fn foo(&self) -> u32 { + todo!() + } +} +``` + + +### `add_label_to_loop` +**Source:** [add_label_to_loop.rs](crates/ide-assists/src/handlers/add_label_to_loop.rs#9) + +Adds a label to a loop. + +#### Before +```rust +fn main() { + loop┃ { + break; + continue; + } +} +``` + +#### After +```rust +fn main() { + 'l: loop { + break 'l; + continue 'l; + } +} +``` + + +### `add_lifetime_to_type` +**Source:** [add_lifetime_to_type.rs](crates/ide-assists/src/handlers/add_lifetime_to_type.rs#5) + +Adds a new lifetime to a struct, enum or union. + +#### Before +```rust +struct Point { + x: &┃u32, + y: u32, +} +``` + +#### After +```rust +struct Point<'a> { + x: &'a u32, + y: u32, +} +``` + + +### `add_missing_match_arms` +**Source:** [add_missing_match_arms.rs](crates/ide-assists/src/handlers/add_missing_match_arms.rs#13) + +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 { + ┃Action::Move { distance } => todo!(), + Action::Stop => todo!(), + } +} +``` + + +### `add_return_type` +**Source:** [add_return_type.rs](crates/ide-assists/src/handlers/add_return_type.rs#6) + +Adds the return type to a function or closure inferred from its tail expression if it doesn't have a return +type specified. This assists is useable in a functions or closures tail expression or return type position. + +#### Before +```rust +fn foo() { 4┃2i32 } +``` + +#### After +```rust +fn foo() -> i32 { 42i32 } +``` + + +### `add_turbo_fish` +**Source:** [add_turbo_fish.rs](crates/ide-assists/src/handlers/add_turbo_fish.rs#10) + +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:_}>(); +} +``` + + +### `apply_demorgan` +**Source:** [apply_demorgan.rs](crates/ide-assists/src/handlers/apply_demorgan.rs#17) + +Apply https://en.wikipedia.org/wiki/De_Morgan%27s_laws[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 `&&`. + +#### Before +```rust +fn main() { + if x != 4 ||┃ y < 3.14 {} +} +``` + +#### After +```rust +fn main() { + if !(x == 4 && y >= 3.14) {} +} +``` + + +### `apply_demorgan_iterator` +**Source:** [apply_demorgan.rs](crates/ide-assists/src/handlers/apply_demorgan.rs#153) + +Apply https://en.wikipedia.org/wiki/De_Morgan%27s_laws[De Morgan's law] to +`Iterator::all` and `Iterator::any`. + +This transforms expressions of the form `!iter.any(|x| predicate(x))` into +`iter.all(|x| !predicate(x))` and vice versa. This also works the other way for +`Iterator::all` into `Iterator::any`. + +#### Before +```rust +fn main() { + let arr = [1, 2, 3]; + if !arr.into_iter().┃any(|num| num == 4) { + println!("foo"); + } +} +``` + +#### After +```rust +fn main() { + let arr = [1, 2, 3]; + if arr.into_iter().all(|num| num != 4) { + println!("foo"); + } +} +``` + + +### `auto_import` +**Source:** [auto_import.rs](crates/ide-assists/src/handlers/auto_import.rs#71) + +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(); +} +``` + + +### `bind_unused_param` +**Source:** [bind_unused_param.rs](crates/ide-assists/src/handlers/bind_unused_param.rs#12) + +Binds unused function parameter to an underscore. + +#### Before +```rust +fn some_function(x: i32┃) {} +``` + +#### After +```rust +fn some_function(x: i32) { + let _ = x; +} +``` + + +### `bool_to_enum` +**Source:** [bool_to_enum.rs](crates/ide-assists/src/handlers/bool_to_enum.rs#25) + +This converts boolean local variables, fields, constants, and statics into a new +enum with two variants `Bool::True` and `Bool::False`, as well as replacing +all assignments with the variants and replacing all usages with `== Bool::True` or +`== Bool::False`. + +#### Before +```rust +fn main() { + let ┃bool = true; + + if bool { + println!("foo"); + } +} +``` + +#### After +```rust +#[derive(PartialEq, Eq)] +enum Bool { True, False } + +fn main() { + let bool = Bool::True; + + if bool == Bool::True { + println!("foo"); + } +} +``` + + +### `change_visibility` +**Source:** [change_visibility.rs](crates/ide-assists/src/handlers/change_visibility.rs#13) + +Adds or changes existing visibility specifier. + +#### Before +```rust +┃fn frobnicate() {} +``` + +#### After +```rust +pub(crate) fn frobnicate() {} +``` + + +### `convert_bool_then_to_if` +**Source:** [convert_bool_then.rs](crates/ide-assists/src/handlers/convert_bool_then.rs#131) + +Converts a `bool::then` method call to an equivalent if expression. + +#### Before +```rust +fn main() { + (0 == 0).then┃(|| val) +} +``` + +#### After +```rust +fn main() { + if 0 == 0 { + Some(val) + } else { + None + } +} +``` + + +### `convert_for_loop_with_for_each` +**Source:** [convert_iter_for_each_to_for.rs](crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#76) + +Converts a for loop into a for_each loop on the Iterator. + +#### Before +```rust +fn main() { + let x = vec![1, 2, 3]; + for┃ v in x { + let y = v * 2; + } +} +``` + +#### After +```rust +fn main() { + let x = vec![1, 2, 3]; + x.into_iter().for_each(|v| { + let y = v * 2; + }); +} +``` + + +### `convert_if_to_bool_then` +**Source:** [convert_bool_then.rs](crates/ide-assists/src/handlers/convert_bool_then.rs#20) + +Converts an if expression into a corresponding `bool::then` call. + +#### Before +```rust +fn main() { + if┃ cond { + Some(val) + } else { + None + } +} +``` + +#### After +```rust +fn main() { + cond.then(|| val) +} +``` + + +### `convert_integer_literal` +**Source:** [convert_integer_literal.rs](crates/ide-assists/src/handlers/convert_integer_literal.rs#5) + +Converts the base of integer literals to other bases. + +#### Before +```rust +const _: i32 = 10┃; +``` + +#### After +```rust +const _: i32 = 0b1010; +``` + + +### `convert_into_to_from` +**Source:** [convert_into_to_from.rs](crates/ide-assists/src/handlers/convert_into_to_from.rs#8) + +Converts an Into impl to an equivalent From impl. + +#### Before +```rust +impl ┃Into for usize { + fn into(self) -> Thing { + Thing { + b: self.to_string(), + a: self + } + } +} +``` + +#### After +```rust +impl From for Thing { + fn from(val: usize) -> Self { + Thing { + b: val.to_string(), + a: val + } + } +} +``` + + +### `convert_iter_for_each_to_for` +**Source:** [convert_iter_for_each_to_for.rs](crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#11) + +Converts an Iterator::for_each function into a for loop. + +#### Before +```rust +fn main() { + let iter = iter::repeat((9, 2)); + iter.for_each┃(|(x, y)| { + println!("x: {}, y: {}", x, y); + }); +} +``` + +#### After +```rust +fn main() { + let iter = iter::repeat((9, 2)); + for (x, y) in iter { + println!("x: {}, y: {}", x, y); + } +} +``` + + +### `convert_let_else_to_match` +**Source:** [convert_let_else_to_match.rs](crates/ide-assists/src/handlers/convert_let_else_to_match.rs#8) + +Converts let-else statement to let statement and match expression. + +#### Before +```rust +fn main() { + let Ok(mut x) = f() else┃ { return }; +} +``` + +#### After +```rust +fn main() { + let mut x = match f() { + Ok(x) => x, + _ => return, + }; +} +``` + + +### `convert_match_to_let_else` +**Source:** [convert_match_to_let_else.rs](crates/ide-assists/src/handlers/convert_match_to_let_else.rs#12) + +Converts let statement with match initializer to let-else statement. + +#### Before +```rust +fn foo(opt: Option<()>) { + let val┃ = match opt { + Some(it) => it, + None => return, + }; +} +``` + +#### After +```rust +fn foo(opt: Option<()>) { + let Some(val) = opt else { return }; +} +``` + + +### `convert_named_struct_to_tuple_struct` +**Source:** [convert_named_struct_to_tuple_struct.rs](crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs#11) + +Converts struct with named fields to tuple struct, and analogously for enum variants with named +fields. + +#### Before +```rust +struct Point┃ { x: f32, y: f32 } + +impl Point { + pub fn new(x: f32, y: f32) -> Self { + Point { x, y } + } + + pub fn x(&self) -> f32 { + self.x + } + + pub fn y(&self) -> f32 { + self.y + } +} +``` + +#### After +```rust +struct Point(f32, f32); + +impl Point { + pub fn new(x: f32, y: f32) -> Self { + Point(x, y) + } + + pub fn x(&self) -> f32 { + self.0 + } + + pub fn y(&self) -> f32 { + self.1 + } +} +``` + + +### `convert_nested_function_to_closure` +**Source:** [convert_nested_function_to_closure.rs](crates/ide-assists/src/handlers/convert_nested_function_to_closure.rs#7) + +Converts a function that is defined within the body of another function into a closure. + +#### Before +```rust +fn main() { + fn fo┃o(label: &str, number: u64) { + println!("{}: {}", label, number); + } + + foo("Bar", 100); +} +``` + +#### After +```rust +fn main() { + let foo = |label: &str, number: u64| { + println!("{}: {}", label, number); + }; + + foo("Bar", 100); +} +``` + + +### `convert_to_guarded_return` +**Source:** [convert_to_guarded_return.rs](crates/ide-assists/src/handlers/convert_to_guarded_return.rs#21) + +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(); +} +``` + + +### `convert_tuple_return_type_to_struct` +**Source:** [convert_tuple_return_type_to_struct.rs](crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs#20) + +This converts the return type of a function from a tuple type +into a tuple struct and updates the body accordingly. + +#### Before +```rust +fn bar() { + let (a, b, c) = foo(); +} + +fn foo() -> (┃u32, u32, u32) { + (1, 2, 3) +} +``` + +#### After +```rust +fn bar() { + let FooResult(a, b, c) = foo(); +} + +struct FooResult(u32, u32, u32); + +fn foo() -> FooResult { + FooResult(1, 2, 3) +} +``` + + +### `convert_tuple_struct_to_named_struct` +**Source:** [convert_tuple_struct_to_named_struct.rs](crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs#10) + +Converts tuple struct to struct with named fields, and analogously for tuple enum variants. + +#### Before +```rust +struct Point┃(f32, f32); + +impl Point { + pub fn new(x: f32, y: f32) -> Self { + Point(x, y) + } + + pub fn x(&self) -> f32 { + self.0 + } + + pub fn y(&self) -> f32 { + self.1 + } +} +``` + +#### After +```rust +struct Point { field1: f32, field2: f32 } + +impl Point { + pub fn new(x: f32, y: f32) -> Self { + Point { field1: x, field2: y } + } + + pub fn x(&self) -> f32 { + self.field1 + } + + pub fn y(&self) -> f32 { + self.field2 + } +} +``` + + +### `convert_two_arm_bool_match_to_matches_macro` +**Source:** [convert_two_arm_bool_match_to_matches_macro.rs](crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs#8) + +Convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation. + +#### Before +```rust +fn main() { + match scrutinee┃ { + Some(val) if val.cond() => true, + _ => false, + } +} +``` + +#### After +```rust +fn main() { + matches!(scrutinee, Some(val) if val.cond()) +} +``` + + +### `convert_while_to_loop` +**Source:** [convert_while_to_loop.rs](crates/ide-assists/src/handlers/convert_while_to_loop.rs#19) + +Replace a while with a loop. + +#### Before +```rust +fn main() { + ┃while cond { + foo(); + } +} +``` + +#### After +```rust +fn main() { + loop { + if !cond { + break; + } + foo(); + } +} +``` + + +### `destructure_tuple_binding` +**Source:** [destructure_tuple_binding.rs](crates/ide-assists/src/handlers/destructure_tuple_binding.rs#13) + +Destructures a tuple binding in place. + +#### Before +```rust +fn main() { + let ┃t = (1,2); + let v = t.0; +} +``` + +#### After +```rust +fn main() { + let (┃_0, _1) = (1,2); + let v = _0; +} +``` + + +### `desugar_doc_comment` +**Source:** [desugar_doc_comment.rs](crates/ide-assists/src/handlers/desugar_doc_comment.rs#14) + +Desugars doc-comments to the attribute form. + +#### Before +```rust +/// Multi-line┃ +/// comment +``` + +#### After +```rust +#[doc = r"Multi-line +comment"] +``` + + +### `expand_glob_import` +**Source:** [expand_glob_import.rs](crates/ide-assists/src/handlers/expand_glob_import.rs#18) + +Expands glob imports. + +#### Before +```rust +mod foo { + pub struct Bar; + pub struct Baz; +} + +use foo::*┃; + +fn qux(bar: Bar, baz: Baz) {} +``` + +#### After +```rust +mod foo { + pub struct Bar; + pub struct Baz; +} + +use foo::{Bar, Baz}; + +fn qux(bar: Bar, baz: Baz) {} +``` + + +### `extract_expressions_from_format_string` +**Source:** [extract_expressions_from_format_string.rs](crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs#13) + +Move an expression out of a format string. + +#### Before +```rust +fn main() { + print!("{var} {x + 1}┃"); +} +``` + +#### After +```rust +fn main() { + print!("{var} {}"┃, x + 1); +} +``` + + +### `extract_function` +**Source:** [extract_function.rs](crates/ide-assists/src/handlers/extract_function.rs#39) + +Extracts selected statements and comments into new function. + +#### Before +```rust +fn main() { + let n = 1; + ┃let m = n + 2; + // calculate + let k = m + n;┃ + let g = 3; +} +``` + +#### After +```rust +fn main() { + let n = 1; + fun_name(n); + let g = 3; +} + +fn ┃fun_name(n: i32) { + let m = n + 2; + // calculate + let k = m + n; +} +``` + + +### `extract_module` +**Source:** [extract_module.rs](crates/ide-assists/src/handlers/extract_module.rs#32) + +Extracts a selected region as separate module. All the references, visibility and imports are +resolved. + +#### Before +```rust +┃fn foo(name: i32) -> i32 { + name + 1 +}┃ + +fn bar(name: i32) -> i32 { + name + 2 +} +``` + +#### After +```rust +mod modname { + pub(crate) fn foo(name: i32) -> i32 { + name + 1 + } +} + +fn bar(name: i32) -> i32 { + name + 2 +} +``` + + +### `extract_struct_from_enum_variant` +**Source:** [extract_struct_from_enum_variant.rs](crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs#25) + +Extracts a struct from enum variant. + +#### Before +```rust +enum A { ┃One(u32, u32) } +``` + +#### After +```rust +struct One(u32, u32); + +enum A { One(One) } +``` + + +### `extract_type_alias` +**Source:** [extract_type_alias.rs](crates/ide-assists/src/handlers/extract_type_alias.rs#10) + +Extracts the selected type as a type alias. + +#### Before +```rust +struct S { + field: ┃(u8, u8, u8)┃, +} +``` + +#### After +```rust +type ┃Type = (u8, u8, u8); + +struct S { + field: Type, +} +``` + + +### `extract_variable` +**Source:** [extract_variable.rs](crates/ide-assists/src/handlers/extract_variable.rs#15) + +Extracts subexpression into a variable. + +#### Before +```rust +fn main() { + ┃(1 + 2)┃ * 4; +} +``` + +#### After +```rust +fn main() { + let ┃var_name = (1 + 2); + var_name * 4; +} +``` + + +### `fix_visibility` +**Source:** [fix_visibility.rs](crates/ide-assists/src/handlers/fix_visibility.rs#12) + +Makes inaccessible item public. + +#### Before +```rust +mod m { + fn frobnicate() {} +} +fn main() { + m::frobnicate┃(); +} +``` + +#### After +```rust +mod m { + ┃pub(crate) fn frobnicate() {} +} +fn main() { + m::frobnicate(); +} +``` + + +### `flip_binexpr` +**Source:** [flip_binexpr.rs](crates/ide-assists/src/handlers/flip_binexpr.rs#5) + +Flips operands of a binary expression. + +#### Before +```rust +fn main() { + let _ = 90 +┃ 2; +} +``` + +#### After +```rust +fn main() { + let _ = 2 + 90; +} +``` + + +### `flip_comma` +**Source:** [flip_comma.rs](crates/ide-assists/src/handlers/flip_comma.rs#5) + +Flips two comma-separated items. + +#### Before +```rust +fn main() { + ((1, 2),┃ (3, 4)); +} +``` + +#### After +```rust +fn main() { + ((3, 4), (1, 2)); +} +``` + + +### `flip_trait_bound` +**Source:** [flip_trait_bound.rs](crates/ide-assists/src/handlers/flip_trait_bound.rs#9) + +Flips two trait bounds. + +#### Before +```rust +fn foo() { } +``` + +#### After +```rust +fn foo() { } +``` + + +### `generate_constant` +**Source:** [generate_constant.rs](crates/ide-assists/src/handlers/generate_constant.rs#13) + +Generate a named constant. + +#### Before +```rust +struct S { i: usize } +impl S { pub fn new(n: usize) {} } +fn main() { + let v = S::new(CAPA┃CITY); +} +``` + +#### After +```rust +struct S { i: usize } +impl S { pub fn new(n: usize) {} } +fn main() { + const CAPACITY: usize = ┃; + let v = S::new(CAPACITY); +} +``` + + +### `generate_default_from_enum_variant` +**Source:** [generate_default_from_enum_variant.rs](crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs#6) + +Adds a Default impl for an enum using a variant. + +#### Before +```rust +enum Version { + Undefined, + Minor┃, + Major, +} +``` + +#### After +```rust +enum Version { + Undefined, + Minor, + Major, +} + +impl Default for Version { + fn default() -> Self { + Self::Minor + } +} +``` + + +### `generate_default_from_new` +**Source:** [generate_default_from_new.rs](crates/ide-assists/src/handlers/generate_default_from_new.rs#13) + +Generates default implementation from new method. + +#### Before +```rust +struct Example { _inner: () } + +impl Example { + pub fn n┃ew() -> Self { + Self { _inner: () } + } +} +``` + +#### After +```rust +struct Example { _inner: () } + +impl Example { + pub fn new() -> Self { + Self { _inner: () } + } +} + +impl Default for Example { + fn default() -> Self { + Self::new() + } +} +``` + + +### `generate_delegate_methods` +**Source:** [generate_delegate_methods.rs](crates/ide-assists/src/handlers/generate_delegate_methods.rs#16) + +Generate delegate methods. + +#### Before +```rust +struct Age(u8); +impl Age { + fn age(&self) -> u8 { + self.0 + } +} + +struct Person { + ag┃e: Age, +} +``` + +#### After +```rust +struct Age(u8); +impl Age { + fn age(&self) -> u8 { + self.0 + } +} + +struct Person { + age: Age, +} + +impl Person { + ┃fn age(&self) -> u8 { + self.age.age() + } +} +``` + + +### `generate_delegate_trait` +**Source:** [generate_delegate_trait.rs](crates/ide-assists/src/handlers/generate_delegate_trait.rs#23) + +Generate delegate trait implementation for `StructField`s. + +#### Before +```rust +trait SomeTrait { + type T; + fn fn_(arg: u32) -> u32; + fn method_(&mut self) -> bool; +} +struct A; +impl SomeTrait for A { + type T = u32; + + fn fn_(arg: u32) -> u32 { + 42 + } + + fn method_(&mut self) -> bool { + false + } +} +struct B { + a┃: A, +} +``` + +#### After +```rust +trait SomeTrait { + type T; + fn fn_(arg: u32) -> u32; + fn method_(&mut self) -> bool; +} +struct A; +impl SomeTrait for A { + type T = u32; + + fn fn_(arg: u32) -> u32 { + 42 + } + + fn method_(&mut self) -> bool { + false + } +} +struct B { + a: A, +} + +impl SomeTrait for B { + type T = ::T; + + fn fn_(arg: u32) -> u32 { + ::fn_(arg) + } + + fn method_(&mut self) -> bool { + ::method_( &mut self.a ) + } +} +``` + + +### `generate_deref` +**Source:** [generate_deref.rs](crates/ide-assists/src/handlers/generate_deref.rs#16) + +Generate `Deref` impl using the given struct field. + +#### Before +```rust +struct A; +struct B { + ┃a: A +} +``` + +#### After +```rust +struct A; +struct B { + a: A +} + +impl core::ops::Deref for B { + type Target = A; + + fn deref(&self) -> &Self::Target { + &self.a + } +} +``` + + +### `generate_derive` +**Source:** [generate_derive.rs](crates/ide-assists/src/handlers/generate_derive.rs#8) + +Adds a new `#[derive()]` clause to a struct or enum. + +#### Before +```rust +struct Point { + x: u32, + y: u32,┃ +} +``` + +#### After +```rust +#[derive(┃)] +struct Point { + x: u32, + y: u32, +} +``` + + +### `generate_doc_example` +**Source:** [generate_documentation_template.rs](crates/ide-assists/src/handlers/generate_documentation_template.rs#76) + +Generates a rustdoc example when editing an item's documentation. + +#### Before +```rust +/// Adds two numbers.┃ +pub fn add(a: i32, b: i32) -> i32 { a + b } +``` + +#### After +```rust +/// Adds two numbers. +/// +/// # Examples +/// +/// ``` +/// use test::add; +/// +/// assert_eq!(add(a, b), ); +/// ``` +pub fn add(a: i32, b: i32) -> i32 { a + b } +``` + + +### `generate_documentation_template` +**Source:** [generate_documentation_template.rs](crates/ide-assists/src/handlers/generate_documentation_template.rs#13) + +Adds a documentation template above a function definition / declaration. + +#### Before +```rust +pub struct S; +impl S { + pub unsafe fn set_len┃(&mut self, len: usize) -> Result<(), std::io::Error> { + /* ... */ + } +} +``` + +#### After +```rust +pub struct S; +impl S { + /// Sets the length of this [`S`]. + /// + /// # Errors + /// + /// This function will return an error if . + /// + /// # Safety + /// + /// . + pub unsafe fn set_len(&mut self, len: usize) -> Result<(), std::io::Error> { + /* ... */ + } +} +``` + + +### `generate_enum_as_method` +**Source:** [generate_enum_projection_method.rs](crates/ide-assists/src/handlers/generate_enum_projection_method.rs#59) + +Generate an `as_` method for this enum variant. + +#### Before +```rust +enum Value { + Number(i32), + Text(String)┃, +} +``` + +#### After +```rust +enum Value { + Number(i32), + Text(String), +} + +impl Value { + fn as_text(&self) -> Option<&String> { + if let Self::Text(v) = self { + Some(v) + } else { + None + } + } +} +``` + + +### `generate_enum_is_method` +**Source:** [generate_enum_is_method.rs](crates/ide-assists/src/handlers/generate_enum_is_method.rs#11) + +Generate an `is_` method for this enum variant. + +#### Before +```rust +enum Version { + Undefined, + Minor┃, + Major, +} +``` + +#### After +```rust +enum Version { + Undefined, + Minor, + Major, +} + +impl Version { + /// Returns `true` if the version is [`Minor`]. + /// + /// [`Minor`]: Version::Minor + #[must_use] + fn is_minor(&self) -> bool { + matches!(self, Self::Minor) + } +} +``` + + +### `generate_enum_try_into_method` +**Source:** [generate_enum_projection_method.rs](crates/ide-assists/src/handlers/generate_enum_projection_method.rs#12) + +Generate a `try_into_` method for this enum variant. + +#### Before +```rust +enum Value { + Number(i32), + Text(String)┃, +} +``` + +#### After +```rust +enum Value { + Number(i32), + Text(String), +} + +impl Value { + fn try_into_text(self) -> Result { + if let Self::Text(v) = self { + Ok(v) + } else { + Err(self) + } + } +} +``` + + +### `generate_enum_variant` +**Source:** [generate_enum_variant.rs](crates/ide-assists/src/handlers/generate_enum_variant.rs#10) + +Adds a variant to an enum. + +#### Before +```rust +enum Countries { + Ghana, +} + +fn main() { + let country = Countries::Lesotho┃; +} +``` + +#### After +```rust +enum Countries { + Ghana, + Lesotho, +} + +fn main() { + let country = Countries::Lesotho; +} +``` + + +### `generate_from_impl_for_enum` +**Source:** [generate_from_impl_for_enum.rs](crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs#8) + +Adds a From impl for this 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 { + Self::One(v) + } +} +``` + + +### `generate_function` +**Source:** [generate_function.rs](crates/ide-assists/src/handlers/generate_function.rs#27) + +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!() +} + +``` + + +### `generate_getter` +**Source:** [generate_getter_or_setter.rs](crates/ide-assists/src/handlers/generate_getter_or_setter.rs#73) + +Generate a getter method. + +#### Before +```rust +struct Person { + nam┃e: String, +} +``` + +#### After +```rust +struct Person { + name: String, +} + +impl Person { + fn ┃name(&self) -> &str { + self.name.as_ref() + } +} +``` + + +### `generate_getter_mut` +**Source:** [generate_getter_or_setter.rs](crates/ide-assists/src/handlers/generate_getter_or_setter.rs#113) + +Generate a mut getter method. + +#### Before +```rust +struct Person { + nam┃e: String, +} +``` + +#### After +```rust +struct Person { + name: String, +} + +impl Person { + fn ┃name_mut(&mut self) -> &mut String { + &mut self.name + } +} +``` + + +### `generate_impl` +**Source:** [generate_impl.rs](crates/ide-assists/src/handlers/generate_impl.rs#8) + +Adds a new inherent impl for a type. + +#### Before +```rust +struct Ctx┃ { + data: T, +} +``` + +#### After +```rust +struct Ctx { + data: T, +} + +impl Ctx { + ┃ +} +``` + + +### `generate_is_empty_from_len` +**Source:** [generate_is_empty_from_len.rs](crates/ide-assists/src/handlers/generate_is_empty_from_len.rs#12) + +Generates is_empty implementation from the len method. + +#### Before +```rust +struct MyStruct { data: Vec } + +impl MyStruct { + #[must_use] + p┃ub fn len(&self) -> usize { + self.data.len() + } +} +``` + +#### After +```rust +struct MyStruct { data: Vec } + +impl MyStruct { + #[must_use] + pub fn len(&self) -> usize { + self.data.len() + } + + #[must_use] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} +``` + + +### `generate_mut_trait_impl` +**Source:** [generate_mut_trait_impl.rs](crates/ide-assists/src/handlers/generate_mut_trait_impl.rs#12) + +Adds a IndexMut impl from the `Index` trait. + +#### Before +```rust +pub enum Axis { X = 0, Y = 1, Z = 2 } + +impl core::ops::Index┃ for [T; 3] { + type Output = T; + + fn index(&self, index: Axis) -> &Self::Output { + &self[index as usize] + } +} +``` + +#### After +```rust +pub enum Axis { X = 0, Y = 1, Z = 2 } + +┃impl core::ops::IndexMut for [T; 3] { + fn index_mut(&mut self, index: Axis) -> &mut Self::Output { + &self[index as usize] + } +} + +impl core::ops::Index for [T; 3] { + type Output = T; + + fn index(&self, index: Axis) -> &Self::Output { + &self[index as usize] + } +} +``` + + +### `generate_new` +**Source:** [generate_new.rs](crates/ide-assists/src/handlers/generate_new.rs#13) + +Adds a `fn new` for a type. + +#### Before +```rust +struct Ctx { + data: T,┃ +} +``` + +#### After +```rust +struct Ctx { + data: T, +} + +impl Ctx { + fn ┃new(data: T) -> Self { Self { data } } +} +``` + + +### `generate_setter` +**Source:** [generate_getter_or_setter.rs](crates/ide-assists/src/handlers/generate_getter_or_setter.rs#13) + +Generate a setter method. + +#### Before +```rust +struct Person { + nam┃e: String, +} +``` + +#### After +```rust +struct Person { + name: String, +} + +impl Person { + fn ┃set_name(&mut self, name: String) { + self.name = name; + } +} +``` + + +### `generate_trait_from_impl` +**Source:** [generate_trait_from_impl.rs](crates/ide-assists/src/handlers/generate_trait_from_impl.rs#13) + +Generate trait for an already defined inherent impl and convert impl to a trait impl. + +#### Before +```rust +struct Foo([i32; N]); + +macro_rules! const_maker { + ($t:ty, $v:tt) => { + const CONST: $t = $v; + }; +} + +impl Fo┃o { + // Used as an associated constant. + const CONST_ASSOC: usize = N * 4; + + fn create() -> Option<()> { + Some(()) + } + + const_maker! {i32, 7} +} +``` + +#### After +```rust +struct Foo([i32; N]); + +macro_rules! const_maker { + ($t:ty, $v:tt) => { + const CONST: $t = $v; + }; +} + +trait ${0:TraitName} { + // Used as an associated constant. + const CONST_ASSOC: usize = N * 4; + + fn create() -> Option<()>; + + const_maker! {i32, 7} +} + +impl ${0:TraitName} for Foo { + // Used as an associated constant. + const CONST_ASSOC: usize = N * 4; + + fn create() -> Option<()> { + Some(()) + } + + const_maker! {i32, 7} +} +``` + + +### `generate_trait_impl` +**Source:** [generate_impl.rs](crates/ide-assists/src/handlers/generate_impl.rs#56) + +Adds a new trait impl for a type. + +#### Before +```rust +struct ┃Ctx { + data: T, +} +``` + +#### After +```rust +struct Ctx { + data: T, +} + +impl ┃ for Ctx { + +} +``` + + +### `inline_call` +**Source:** [inline_call.rs](crates/ide-assists/src/handlers/inline_call.rs#161) + +Inlines a function or method body creating a `let` statement per parameter unless the parameter +can be inlined. The parameter will be inlined either if it the supplied argument is a simple local +or if the parameter is only accessed inside the function body once. + +#### Before +```rust +fn foo(name: Option<&str>) { + let name = name.unwrap┃(); +} +``` + +#### After +```rust +fn foo(name: Option<&str>) { + let name = match name { + Some(val) => val, + None => panic!("called `Option::unwrap()` on a `None` value"), + }; +} +``` + + +### `inline_const_as_literal` +**Source:** [inline_const_as_literal.rs](crates/ide-assists/src/handlers/inline_const_as_literal.rs#5) + +Evaluate and inline const variable as literal. + +#### Before +```rust +const STRING: &str = "Hello, World!"; + +fn something() -> &'static str { + STRING┃ +} +``` + +#### After +```rust +const STRING: &str = "Hello, World!"; + +fn something() -> &'static str { + "Hello, World!" +} +``` + + +### `inline_into_callers` +**Source:** [inline_call.rs](crates/ide-assists/src/handlers/inline_call.rs#27) + +Inline a function or method body into all of its callers where possible, creating a `let` statement per parameter +unless the parameter can be inlined. The parameter will be inlined either if it the supplied argument is a simple local +or if the parameter is only accessed inside the function body once. +If all calls can be inlined the function will be removed. + +#### Before +```rust +fn print(_: &str) {} +fn foo┃(word: &str) { + if !word.is_empty() { + print(word); + } +} +fn bar() { + foo("안녕하세요"); + foo("여러분"); +} +``` + +#### After +```rust +fn print(_: &str) {} + +fn bar() { + { + let word = "안녕하세요"; + if !word.is_empty() { + print(word); + } + }; + { + let word = "여러분"; + if !word.is_empty() { + print(word); + } + }; +} +``` + + +### `inline_local_variable` +**Source:** [inline_local_variable.rs](crates/ide-assists/src/handlers/inline_local_variable.rs#18) + +Inlines a local variable. + +#### Before +```rust +fn main() { + let x┃ = 1 + 2; + x * 4; +} +``` + +#### After +```rust +fn main() { + (1 + 2) * 4; +} +``` + + +### `inline_macro` +**Source:** [inline_macro.rs](crates/ide-assists/src/handlers/inline_macro.rs#6) + +Takes a macro and inlines it one step. + +#### Before +```rust +macro_rules! num { + (+$($t:tt)+) => (1 + num!($($t )+)); + (-$($t:tt)+) => (-1 + num!($($t )+)); + (+) => (1); + (-) => (-1); +} + +fn main() { + let number = num┃!(+ + + - + +); + println!("{number}"); +} +``` + +#### After +```rust +macro_rules! num { + (+$($t:tt)+) => (1 + num!($($t )+)); + (-$($t:tt)+) => (-1 + num!($($t )+)); + (+) => (1); + (-) => (-1); +} + +fn main() { + let number = 1+num!(+ + - + +); + println!("{number}"); +} +``` + + +### `inline_type_alias` +**Source:** [inline_type_alias.rs](crates/ide-assists/src/handlers/inline_type_alias.rs#105) + +Replace a type alias with its concrete type. + +#### Before +```rust +type A = Vec; + +fn main() { + let a: ┃A; +} +``` + +#### After +```rust +type A = Vec; + +fn main() { + let a: Vec; +} +``` + + +### `inline_type_alias_uses` +**Source:** [inline_type_alias.rs](crates/ide-assists/src/handlers/inline_type_alias.rs#24) + +Inline a type alias into all of its uses where possible. + +#### Before +```rust +type ┃A = i32; +fn id(x: A) -> A { + x +}; +fn foo() { + let _: A = 3; +} +``` + +#### After +```rust + +fn id(x: i32) -> i32 { + x +}; +fn foo() { + let _: i32 = 3; +} +``` + + +### `into_to_qualified_from` +**Source:** [into_to_qualified_from.rs](crates/ide-assists/src/handlers/into_to_qualified_from.rs#10) + +Convert an `into` method call to a fully qualified `from` call. + +#### Before +```rust +//- minicore: from +struct B; +impl From for B { + fn from(a: i32) -> Self { + B + } +} + +fn main() -> () { + let a = 3; + let b: B = a.in┃to(); +} +``` + +#### After +```rust +struct B; +impl From for B { + fn from(a: i32) -> Self { + B + } +} + +fn main() -> () { + let a = 3; + let b: B = B::from(a); +} +``` + + +### `introduce_named_generic` +**Source:** [introduce_named_generic.rs](crates/ide-assists/src/handlers/introduce_named_generic.rs#8) + +Replaces `impl Trait` function argument with the named generic. + +#### Before +```rust +fn foo(bar: ┃impl Bar) {} +``` + +#### After +```rust +fn foo<┃B: Bar>(bar: B) {} +``` + + +### `introduce_named_lifetime` +**Source:** [introduce_named_lifetime.rs](crates/ide-assists/src/handlers/introduce_named_lifetime.rs#13) + +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, + } + } +} +``` + + +### `invert_if` +**Source:** [invert_if.rs](crates/ide-assists/src/handlers/invert_if.rs#13) + +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 } +} +``` + + +### `line_to_block` +**Source:** [convert_comment_block.rs](crates/ide-assists/src/handlers/convert_comment_block.rs#9) + +Converts comments between block and single-line form. + +#### Before +```rust + // Multi-line┃ + // comment +``` + +#### After +```rust + /* + Multi-line + comment + */ +``` + + +### `make_raw_string` +**Source:** [raw_string.rs](crates/ide-assists/src/handlers/raw_string.rs#7) + +Adds `r#` to a plain string literal. + +#### Before +```rust +fn main() { + "Hello,┃ World!"; +} +``` + +#### After +```rust +fn main() { + r#"Hello, World!"#; +} +``` + + +### `make_usual_string` +**Source:** [raw_string.rs](crates/ide-assists/src/handlers/raw_string.rs#47) + +Turns a raw string into a plain string. + +#### Before +```rust +fn main() { + r#"Hello,┃ "World!""#; +} +``` + +#### After +```rust +fn main() { + "Hello, \"World!\""; +} +``` + + +### `merge_imports` +**Source:** [merge_imports.rs](crates/ide-assists/src/handlers/merge_imports.rs#17) + +Merges two imports with a common prefix. + +#### Before +```rust +use std::┃fmt::Formatter; +use std::io; +``` + +#### After +```rust +use std::{fmt::Formatter, io}; +``` + + +### `merge_match_arms` +**Source:** [merge_match_arms.rs](crates/ide-assists/src/handlers/merge_match_arms.rs#11) + +Merges the current match arm with the following if their bodies are identical. + +#### 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(), + } +} +``` + + +### `move_arm_cond_to_match_guard` +**Source:** [move_guard.rs](crates/ide-assists/src/handlers/move_guard.rs#69) + +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(), + _ => (), + } +} +``` + + +### `move_bounds_to_where_clause` +**Source:** [move_bounds.rs](crates/ide-assists/src/handlers/move_bounds.rs#12) + +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) +} +``` + + +### `move_const_to_impl` +**Source:** [move_const_to_impl.rs](crates/ide-assists/src/handlers/move_const_to_impl.rs#14) + +Move a local constant item in a method to impl's associated constant. All the references will be +qualified with `Self::`. + +#### Before +```rust +struct S; +impl S { + fn foo() -> usize { + /// The answer. + const C┃: usize = 42; + + C * C + } +} +``` + +#### After +```rust +struct S; +impl S { + /// The answer. + const C: usize = 42; + + fn foo() -> usize { + Self::C * Self::C + } +} +``` + + +### `move_from_mod_rs` +**Source:** [move_from_mod_rs.rs](crates/ide-assists/src/handlers/move_from_mod_rs.rs#12) + +Moves xxx/mod.rs to xxx.rs. + +#### Before +```rust +//- /main.rs +mod a; +//- /a/mod.rs +┃fn t() {}┃ +``` + +#### After +```rust +fn t() {} +``` + + +### `move_guard_to_arm_body` +**Source:** [move_guard.rs](crates/ide-assists/src/handlers/move_guard.rs#8) + +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() + }, + _ => (), + } +} +``` + + +### `move_module_to_file` +**Source:** [move_module_to_file.rs](crates/ide-assists/src/handlers/move_module_to_file.rs#14) + +Moves inline module's contents to a separate file. + +#### Before +```rust +mod ┃foo { + fn t() {} +} +``` + +#### After +```rust +mod foo; +``` + + +### `move_to_mod_rs` +**Source:** [move_to_mod_rs.rs](crates/ide-assists/src/handlers/move_to_mod_rs.rs#12) + +Moves xxx.rs to xxx/mod.rs. + +#### Before +```rust +//- /main.rs +mod a; +//- /a.rs +┃fn t() {}┃ +``` + +#### After +```rust +fn t() {} +``` + + +### `promote_local_to_const` +**Source:** [promote_local_to_const.rs](crates/ide-assists/src/handlers/promote_local_to_const.rs#16) + +Promotes a local variable to a const item changing its name to a `SCREAMING_SNAKE_CASE` variant +if the local uses no non-const expressions. + +#### Before +```rust +fn main() { + let foo┃ = true; + + if foo { + println!("It's true"); + } else { + println!("It's false"); + } +} +``` + +#### After +```rust +fn main() { + const ┃FOO: bool = true; + + if FOO { + println!("It's true"); + } else { + println!("It's false"); + } +} +``` + + +### `pull_assignment_up` +**Source:** [pull_assignment_up.rs](crates/ide-assists/src/handlers/pull_assignment_up.rs#11) + +Extracts variable assignment to outside an if or match statement. + +#### Before +```rust +fn main() { + let mut foo = 6; + + if true { + ┃foo = 5; + } else { + foo = 4; + } +} +``` + +#### After +```rust +fn main() { + let mut foo = 6; + + foo = if true { + 5 + } else { + 4 + }; +} +``` + + +### `qualify_method_call` +**Source:** [qualify_method_call.rs](crates/ide-assists/src/handlers/qualify_method_call.rs#10) + +Replaces the method call with a qualified function call. + +#### Before +```rust +struct Foo; +impl Foo { + fn foo(&self) {} +} +fn main() { + let foo = Foo; + foo.fo┃o(); +} +``` + +#### After +```rust +struct Foo; +impl Foo { + fn foo(&self) {} +} +fn main() { + let foo = Foo; + Foo::foo(&foo); +} +``` + + +### `qualify_path` +**Source:** [qualify_path.rs](crates/ide-assists/src/handlers/qualify_path.rs#21) + +If the name is unresolved, provides all possible qualified paths for it. + +#### Before +```rust +fn main() { + let map = HashMap┃::new(); +} +``` + +#### After +```rust +fn main() { + let map = std::collections::HashMap::new(); +} +``` + + +### `reformat_number_literal` +**Source:** [number_representation.rs](crates/ide-assists/src/handlers/number_representation.rs#7) + +Adds or removes separators from integer literal. + +#### Before +```rust +const _: i32 = 1012345┃; +``` + +#### After +```rust +const _: i32 = 1_012_345; +``` + + +### `remove_dbg` +**Source:** [remove_dbg.rs](crates/ide-assists/src/handlers/remove_dbg.rs#9) + +Removes `dbg!()` macro call. + +#### Before +```rust +fn main() { + let x = ┃dbg!(42 * dbg!(4 + 2));┃ +} +``` + +#### After +```rust +fn main() { + let x = 42 * (4 + 2); +} +``` + + +### `remove_hash` +**Source:** [raw_string.rs](crates/ide-assists/src/handlers/raw_string.rs#117) + +Removes a hash from a raw string literal. + +#### Before +```rust +fn main() { + r#"Hello,┃ World!"#; +} +``` + +#### After +```rust +fn main() { + r"Hello, World!"; +} +``` + + +### `remove_mut` +**Source:** [remove_mut.rs](crates/ide-assists/src/handlers/remove_mut.rs#5) + +Removes the `mut` keyword. + +#### Before +```rust +impl Walrus { + fn feed(&mut┃ self, amount: u32) {} +} +``` + +#### After +```rust +impl Walrus { + fn feed(&self, amount: u32) {} +} +``` + + +### `remove_parentheses` +**Source:** [remove_parentheses.rs](crates/ide-assists/src/handlers/remove_parentheses.rs#5) + +Removes redundant parentheses. + +#### Before +```rust +fn main() { + _ = ┃(2) + 2; +} +``` + +#### After +```rust +fn main() { + _ = 2 + 2; +} +``` + + +### `remove_unused_imports` +**Source:** [remove_unused_imports.rs](crates/ide-assists/src/handlers/remove_unused_imports.rs#15) + +Removes any use statements in the current selection that are unused. + +#### Before +```rust +struct X(); +mod foo { + use super::X┃; +} +``` + +#### After +```rust +struct X(); +mod foo { +} +``` + + +### `remove_unused_param` +**Source:** [remove_unused_param.rs](crates/ide-assists/src/handlers/remove_unused_param.rs#15) + +Removes unused function parameter. + +#### Before +```rust +fn frobnicate(x: i32┃) {} + +fn main() { + frobnicate(92); +} +``` + +#### After +```rust +fn frobnicate() {} + +fn main() { + frobnicate(); +} +``` + + +### `reorder_fields` +**Source:** [reorder_fields.rs](crates/ide-assists/src/handlers/reorder_fields.rs#8) + +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} +``` + + +### `reorder_impl_items` +**Source:** [reorder_impl_items.rs](crates/ide-assists/src/handlers/reorder_impl_items.rs#11) + +Reorder the items of an `impl Trait`. The items will be ordered +in the same order as in the trait definition. + +#### Before +```rust +trait Foo { + type A; + const B: u8; + fn c(); +} + +struct Bar; +┃impl Foo for Bar┃ { + const B: u8 = 17; + fn c() {} + type A = String; +} +``` + +#### After +```rust +trait Foo { + type A; + const B: u8; + fn c(); +} + +struct Bar; +impl Foo for Bar { + type A = String; + const B: u8 = 17; + fn c() {} +} +``` + + +### `replace_arith_with_checked` +**Source:** [replace_arith_op.rs](crates/ide-assists/src/handlers/replace_arith_op.rs#9) + +Replaces arithmetic on integers with the `checked_*` equivalent. + +#### Before +```rust +fn main() { + let x = 1 ┃+ 2; +} +``` + +#### After +```rust +fn main() { + let x = 1.checked_add(2); +} +``` + + +### `replace_arith_with_saturating` +**Source:** [replace_arith_op.rs](crates/ide-assists/src/handlers/replace_arith_op.rs#28) + +Replaces arithmetic on integers with the `saturating_*` equivalent. + +#### Before +```rust +fn main() { + let x = 1 ┃+ 2; +} +``` + +#### After +```rust +fn main() { + let x = 1.saturating_add(2); +} +``` + + +### `replace_arith_with_wrapping` +**Source:** [replace_arith_op.rs](crates/ide-assists/src/handlers/replace_arith_op.rs#50) + +Replaces arithmetic on integers with the `wrapping_*` equivalent. + +#### Before +```rust +fn main() { + let x = 1 ┃+ 2; +} +``` + +#### After +```rust +fn main() { + let x = 1.wrapping_add(2); +} +``` + + +### `replace_char_with_string` +**Source:** [replace_string_with_char.rs](crates/ide-assists/src/handlers/replace_string_with_char.rs#51) + +Replace a char literal with a string literal. + +#### Before +```rust +fn main() { + find('{┃'); +} +``` + +#### After +```rust +fn main() { + find("{"); +} +``` + + +### `replace_derive_with_manual_impl` +**Source:** [replace_derive_with_manual_impl.rs](crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs#18) + +Converts a `derive` impl into a manual one. + +#### Before +```rust +#[derive(Deb┃ug, Display)] +struct S; +``` + +#### After +```rust +#[derive(Display)] +struct S; + +impl Debug for S { + ┃fn fmt(&self, f: &mut Formatter) -> Result<()> { + f.debug_struct("S").finish() + } +} +``` + + +### `replace_if_let_with_match` +**Source:** [replace_if_let_with_match.rs](crates/ide-assists/src/handlers/replace_if_let_with_match.rs#24) + +Replaces a `if let` expression 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(), + } +} +``` + + +### `replace_is_some_with_if_let_some` +**Source:** [replace_is_method_with_if_let_method.rs](crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs#5) + +Replace `if x.is_some()` with `if let Some(_tmp) = x` or `if x.is_ok()` with `if let Ok(_tmp) = x`. + +#### Before +```rust +fn main() { + let x = Some(1); + if x.is_som┃e() {} +} +``` + +#### After +```rust +fn main() { + let x = Some(1); + if let Some(${0:x}) = x {} +} +``` + + +### `replace_let_with_if_let` +**Source:** [replace_let_with_if_let.rs](crates/ide-assists/src/handlers/replace_let_with_if_let.rs#15) + +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 } +``` + + +### `replace_match_with_if_let` +**Source:** [replace_if_let_with_match.rs](crates/ide-assists/src/handlers/replace_if_let_with_match.rs#187) + +Replaces a binary `match` with a wildcard pattern and no guards with an `if let` expression. + +#### Before +```rust +enum Action { Move { distance: u32 }, Stop } + +fn handle(action: Action) { + ┃match action { + Action::Move { distance } => foo(distance), + _ => bar(), + } +} +``` + +#### After +```rust +enum Action { Move { distance: u32 }, Stop } + +fn handle(action: Action) { + if let Action::Move { distance } = action { + foo(distance) + } else { + bar() + } +} +``` + + +### `replace_named_generic_with_impl` +**Source:** [replace_named_generic_with_impl.rs](crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs#19) + +Replaces named generic with an `impl Trait` in function argument. + +#### Before +```rust +fn new>(location: P) -> Self {} +``` + +#### After +```rust +fn new(location: impl AsRef) -> Self {} +``` + + +### `replace_qualified_name_with_use` +**Source:** [replace_qualified_name_with_use.rs](crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs#13) + +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) {} +``` + + +### `replace_string_with_char` +**Source:** [replace_string_with_char.rs](crates/ide-assists/src/handlers/replace_string_with_char.rs#11) + +Replace string literal with char literal. + +#### Before +```rust +fn main() { + find("{┃"); +} +``` + +#### After +```rust +fn main() { + find('{'); +} +``` + + +### `replace_try_expr_with_match` +**Source:** [replace_try_expr_with_match.rs](crates/ide-assists/src/handlers/replace_try_expr_with_match.rs#18) + +Replaces a `try` expression with a `match` expression. + +#### Before +```rust +fn handle() { + let pat = Some(true)┃?; +} +``` + +#### After +```rust +fn handle() { + let pat = match Some(true) { + Some(it) => it, + None => return None, + }; +} +``` + + +### `replace_turbofish_with_explicit_type` +**Source:** [replace_turbofish_with_explicit_type.rs](crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs#13) + +Converts `::<_>` to an explicit type assignment. + +#### Before +```rust +fn make() -> T { ) } +fn main() { + let a = make┃::(); +} +``` + +#### After +```rust +fn make() -> T { ) } +fn main() { + let a: i32 = make(); +} +``` + + +### `replace_with_eager_method` +**Source:** [replace_method_eager_lazy.rs](crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#89) + +Replace `unwrap_or_else` with `unwrap_or` and `ok_or_else` with `ok_or`. + +#### Before +```rust +fn foo() { + let a = Some(1); + a.unwra┃p_or_else(|| 2); +} +``` + +#### After +```rust +fn foo() { + let a = Some(1); + a.unwrap_or(2); +} +``` + + +### `replace_with_lazy_method` +**Source:** [replace_method_eager_lazy.rs](crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#9) + +Replace `unwrap_or` with `unwrap_or_else` and `ok_or` with `ok_or_else`. + +#### Before +```rust +fn foo() { + let a = Some(1); + a.unwra┃p_or(2); +} +``` + +#### After +```rust +fn foo() { + let a = Some(1); + a.unwrap_or_else(|| 2); +} +``` + + +### `sort_items` +**Source:** [sort_items.rs](crates/ide-assists/src/handlers/sort_items.rs#12) + +Sorts item members alphabetically: fields, enum variants and methods. + +#### Before +```rust +struct ┃Foo┃ { second: u32, first: String } +``` + +#### After +```rust +struct Foo { first: String, second: u32 } +``` + +--- + +#### Before +```rust +trait ┃Bar┃ { + fn second(&self) -> u32; + fn first(&self) -> String; +} +``` + +#### After +```rust +trait Bar { + fn first(&self) -> String; + fn second(&self) -> u32; +} +``` + +--- + +#### Before +```rust +struct Baz; +impl ┃Baz┃ { + fn second(&self) -> u32; + fn first(&self) -> String; +} +``` + +#### After +```rust +struct Baz; +impl Baz { + fn first(&self) -> String; + fn second(&self) -> u32; +} +``` + +--- +There is a difference between sorting enum variants: + +#### Before +```rust +enum ┃Animal┃ { + Dog(String, f64), + Cat { weight: f64, name: String }, +} +``` + +#### After +```rust +enum Animal { + Cat { weight: f64, name: String }, + Dog(String, f64), +} +``` + +and sorting a single enum struct variant: + +#### Before +```rust +enum Animal { + Dog(String, f64), + Cat ┃{ weight: f64, name: String }┃, +} +``` + +#### After +```rust +enum Animal { + Dog(String, f64), + Cat { name: String, weight: f64 }, +} +``` + + +### `split_import` +**Source:** [split_import.rs](crates/ide-assists/src/handlers/split_import.rs#5) + +Wraps the tail of import into braces. + +#### Before +```rust +use std::┃collections::HashMap; +``` + +#### After +```rust +use std::{collections::HashMap}; +``` + + +### `toggle_ignore` +**Source:** [toggle_ignore.rs](crates/ide-assists/src/handlers/toggle_ignore.rs#8) + +Adds `#[ignore]` attribute to the test. + +#### Before +```rust +┃#[test] +fn arithmetics { + assert_eq!(2 + 2, 5); +} +``` + +#### After +```rust +#[test] +#[ignore] +fn arithmetics { + assert_eq!(2 + 2, 5); +} +``` + + +### `unmerge_match_arm` +**Source:** [unmerge_match_arm.rs](crates/ide-assists/src/handlers/unmerge_match_arm.rs#10) + +Splits the current match with a `|` pattern into two arms with identical bodies. + +#### Before +```rust +enum Action { Move { distance: u32 }, Stop } + +fn handle(action: Action) { + match action { + Action::Move(..) ┃| Action::Stop => foo(), + } +} +``` + +#### After +```rust +enum Action { Move { distance: u32 }, Stop } + +fn handle(action: Action) { + match action { + Action::Move(..) => foo(), + Action::Stop => foo(), + } +} +``` + + +### `unmerge_use` +**Source:** [unmerge_use.rs](crates/ide-assists/src/handlers/unmerge_use.rs#12) + +Extracts single use item from use list. + +#### Before +```rust +use std::fmt::{Debug, Display┃}; +``` + +#### After +```rust +use std::fmt::{Debug}; +use std::fmt::Display; +``` + + +### `unnecessary_async` +**Source:** [unnecessary_async.rs](crates/ide-assists/src/handlers/unnecessary_async.rs#15) + +Removes the `async` mark from functions which have no `.await` in their body. +Looks for calls to the functions and removes the `.await` on the call site. + +#### Before +```rust +pub async f┃n foo() {} +pub async fn bar() { foo().await } +``` + +#### After +```rust +pub fn foo() {} +pub async fn bar() { foo() } +``` + + +### `unqualify_method_call` +**Source:** [unqualify_method_call.rs](crates/ide-assists/src/handlers/unqualify_method_call.rs#9) + +Transforms universal function call syntax into a method call. + +#### Before +```rust +fn main() { + std::ops::Add::add┃(1, 2); +} +``` + +#### After +```rust +use std::ops::Add; + +fn main() { + 1.add(2); +} +``` + + +### `unwrap_block` +**Source:** [unwrap_block.rs](crates/ide-assists/src/handlers/unwrap_block.rs#12) + +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"); +} +``` + + +### `unwrap_result_return_type` +**Source:** [unwrap_result_return_type.rs](crates/ide-assists/src/handlers/unwrap_result_return_type.rs#13) + +Unwrap the function's return type. + +#### Before +```rust +fn foo() -> Result┃ { Ok(42i32) } +``` + +#### After +```rust +fn foo() -> i32 { 42i32 } +``` + + +### `unwrap_tuple` +**Source:** [unwrap_tuple.rs](crates/ide-assists/src/handlers/unwrap_tuple.rs#8) + +Unwrap the tuple to different variables. + +#### Before +```rust +fn main() { + ┃let (foo, bar) = ("Foo", "Bar"); +} +``` + +#### After +```rust +fn main() { + let foo = "Foo"; + let bar = "Bar"; +} +``` + + +### `wrap_return_type_in_result` +**Source:** [wrap_return_type_in_result.rs](crates/ide-assists/src/handlers/wrap_return_type_in_result.rs#14) + +Wrap the function's return type into Result. + +#### Before +```rust +fn foo() -> i32┃ { 42i32 } +``` + +#### After +```rust +fn foo() -> Result { Ok(42i32) } +``` diff --git a/docs/book/src/configuration/README.md b/docs/book/src/configuration/README.md new file mode 100644 index 000000000000..0d67c46581b3 --- /dev/null +++ b/docs/book/src/configuration/README.md @@ -0,0 +1,51 @@ +# Configuration + +**Source:** +[config.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs) + +The [Installation](#_installation) section contains details on +configuration for some of the editors. In general `rust-analyzer` is +configured via LSP messages, which means that it’s up to the editor to +decide on the exact format and location of configuration files. + +Some clients, such as [VS Code](#vs-code) or [COC plugin in +Vim](#coc-rust-analyzer) provide `rust-analyzer` specific configuration +UIs. Others may require you to know a bit more about the interaction +with `rust-analyzer`. + +For the later category, it might help to know that the initial +configuration is specified as a value of the `initializationOptions` +field of the [`InitializeParams` message, in the LSP +protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize). +The spec says that the field type is `any?`, but `rust-analyzer` is +looking for a JSON object that is constructed using settings from the +list below. Name of the setting, ignoring the `rust-analyzer.` prefix, +is used as a path, and value of the setting becomes the JSON property +value. + +For example, a very common configuration is to enable proc-macro +support, can be achieved by sending this JSON: + + { + "cargo": { + "buildScripts": { + "enable": true, + }, + }, + "procMacro": { + "enable": true, + } + } + +Please consult your editor’s documentation to learn more about how to +configure [LSP +servers](https://microsoft.github.io/language-server-protocol/). + +To verify which configuration is actually used by `rust-analyzer`, set +`RA_LOG` environment variable to `rust_analyzer=info` and look for +config-related messages. Logs should show both the JSON that +`rust-analyzer` sees as well as the updated config. + +This is the list of config options `rust-analyzer` supports: + +{{#include generated.md}} diff --git a/docs/book/src/configuration/generated.md b/docs/book/src/configuration/generated.md new file mode 100644 index 000000000000..ef77e0d3ca18 --- /dev/null +++ b/docs/book/src/configuration/generated.md @@ -0,0 +1,900 @@ +**rust-analyzer.assist.emitMustUse** (default: false) + + Whether to insert #[must_use] when generating `as_` methods +for enum variants. + + +**rust-analyzer.assist.expressionFillDefault** (default: "todo") + + Placeholder expression to use for missing expressions in assists. + + +**rust-analyzer.cachePriming.enable** (default: true) + + Warm up caches on project load. + + +**rust-analyzer.cachePriming.numThreads** (default: 0) + + How many worker threads to handle priming caches. The default `0` means to pick automatically. + + +**rust-analyzer.cargo.autoreload** (default: true) + + Automatically refresh project info via `cargo metadata` on +`Cargo.toml` or `.cargo/config.toml` changes. + + +**rust-analyzer.cargo.buildScripts.enable** (default: true) + + Run build scripts (`build.rs`) for more precise code analysis. + + +**rust-analyzer.cargo.buildScripts.invocationLocation** (default: "workspace") + + Specifies the working directory for running build scripts. +- "workspace": run build scripts for a workspace in the workspace's root directory. + This is incompatible with `#rust-analyzer.cargo.buildScripts.invocationStrategy#` set to `once`. +- "root": run build scripts in the project's root directory. +This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` +is set. + + +**rust-analyzer.cargo.buildScripts.invocationStrategy** (default: "per_workspace") + + Specifies the invocation strategy to use when running the build scripts command. +If `per_workspace` is set, the command will be executed for each workspace. +If `once` is set, the command will be executed once. +This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` +is set. + + +**rust-analyzer.cargo.buildScripts.overrideCommand** (default: null) + + Override the command rust-analyzer uses to run build scripts and +build procedural macros. The command is required to output json +and should therefore include `--message-format=json` or a similar +option. + +If there are multiple linked projects/workspaces, this command is invoked for +each of them, with the working directory being the workspace root +(i.e., the folder containing the `Cargo.toml`). This can be overwritten +by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#` and +`#rust-analyzer.cargo.buildScripts.invocationLocation#`. + +By default, a cargo invocation will be constructed for the configured +targets and features, with the following base command line: + +```bash +cargo check --quiet --workspace --message-format=json --all-targets +``` +. + + +**rust-analyzer.cargo.buildScripts.useRustcWrapper** (default: true) + + Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to +avoid checking unnecessary things. + + +**rust-analyzer.cargo.cfgs** (default: {}) + + List of cfg options to enable with the given values. + + +**rust-analyzer.cargo.extraArgs** (default: []) + + Extra arguments that are passed to every cargo invocation. + + +**rust-analyzer.cargo.extraEnv** (default: {}) + + Extra environment variables that will be set when running cargo, rustc +or other commands within the workspace. Useful for setting RUSTFLAGS. + + +**rust-analyzer.cargo.features** (default: []) + + List of features to activate. + +Set this to `"all"` to pass `--all-features` to cargo. + + +**rust-analyzer.cargo.noDefaultFeatures** (default: false) + + Whether to pass `--no-default-features` to cargo. + + +**rust-analyzer.cargo.sysroot** (default: "discover") + + Relative path to the sysroot, or "discover" to try to automatically find it via +"rustc --print sysroot". + +Unsetting this disables sysroot loading. + +This option does not take effect until rust-analyzer is restarted. + + +**rust-analyzer.cargo.sysrootSrc** (default: null) + + Relative path to the sysroot library sources. If left unset, this will default to +`{cargo.sysroot}/lib/rustlib/src/rust/library`. + +This option does not take effect until rust-analyzer is restarted. + + +**rust-analyzer.cargo.target** (default: null) + + Compilation target override (target triple). + + +**rust-analyzer.cargo.unsetTest** (default: ["core"]) + + Unsets the implicit `#[cfg(test)]` for the specified crates. + + +**rust-analyzer.checkOnSave** (default: true) + + Run the check command for diagnostics on save. + + +**rust-analyzer.check.allTargets** (default: true) + + Check all targets and tests (`--all-targets`). + + +**rust-analyzer.check.command** (default: "check") + + Cargo command to use for `cargo check`. + + +**rust-analyzer.check.extraArgs** (default: []) + + Extra arguments for `cargo check`. + + +**rust-analyzer.check.extraEnv** (default: {}) + + Extra environment variables that will be set when running `cargo check`. +Extends `#rust-analyzer.cargo.extraEnv#`. + + +**rust-analyzer.check.features** (default: null) + + List of features to activate. Defaults to +`#rust-analyzer.cargo.features#`. + +Set to `"all"` to pass `--all-features` to Cargo. + + +**rust-analyzer.check.ignore** (default: []) + + List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore. + +For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,... + + +**rust-analyzer.check.invocationLocation** (default: "workspace") + + Specifies the working directory for running checks. +- "workspace": run checks for workspaces in the corresponding workspaces' root directories. + This falls back to "root" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`. +- "root": run checks in the project's root directory. +This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#` +is set. + + +**rust-analyzer.check.invocationStrategy** (default: "per_workspace") + + Specifies the invocation strategy to use when running the check command. +If `per_workspace` is set, the command will be executed for each workspace. +If `once` is set, the command will be executed once. +This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#` +is set. + + +**rust-analyzer.check.noDefaultFeatures** (default: null) + + Whether to pass `--no-default-features` to Cargo. Defaults to +`#rust-analyzer.cargo.noDefaultFeatures#`. + + +**rust-analyzer.check.overrideCommand** (default: null) + + Override the command rust-analyzer uses instead of `cargo check` for +diagnostics on save. The command is required to output json and +should therefore include `--message-format=json` or a similar option +(if your client supports the `colorDiagnosticOutput` experimental +capability, you can use `--message-format=json-diagnostic-rendered-ansi`). + +If you're changing this because you're using some tool wrapping +Cargo, you might also want to change +`#rust-analyzer.cargo.buildScripts.overrideCommand#`. + +If there are multiple linked projects/workspaces, this command is invoked for +each of them, with the working directory being the workspace root +(i.e., the folder containing the `Cargo.toml`). This can be overwritten +by changing `#rust-analyzer.cargo.check.invocationStrategy#` and +`#rust-analyzer.cargo.check.invocationLocation#`. + +An example command would be: + +```bash +cargo check --workspace --message-format=json --all-targets +``` +. + + +**rust-analyzer.check.targets** (default: null) + + Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty. + +Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g. +`["aarch64-apple-darwin", "x86_64-apple-darwin"]`. + +Aliased as `"checkOnSave.targets"`. + + +**rust-analyzer.completion.autoimport.enable** (default: true) + + Toggles the additional completions that automatically add imports when completed. +Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled. + + +**rust-analyzer.completion.autoself.enable** (default: true) + + Toggles the additional completions that automatically show method calls and field accesses +with `self` prefixed to them when inside a method. + + +**rust-analyzer.completion.callable.snippets** (default: "fill_arguments") + + Whether to add parenthesis and argument snippets when completing function. + + +**rust-analyzer.completion.fullFunctionSignatures.enable** (default: false) + + Whether to show full function/method signatures in completion docs. + + +**rust-analyzer.completion.limit** (default: null) + + Maximum number of completions to return. If `None`, the limit is infinite. + + +**rust-analyzer.completion.postfix.enable** (default: true) + + Whether to show postfix snippets like `dbg`, `if`, `not`, etc. + + +**rust-analyzer.completion.privateEditable.enable** (default: false) + + Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position. + + + **rust-analyzer.completion.snippets.custom** + +Default: + +```{ + "Arc::new": { + "postfix": "arc", + "body": "Arc::new(${receiver})", + "requires": "std::sync::Arc", + "description": "Put the expression into an `Arc`", + "scope": "expr" + }, + "Rc::new": { + "postfix": "rc", + "body": "Rc::new(${receiver})", + "requires": "std::rc::Rc", + "description": "Put the expression into an `Rc`", + "scope": "expr" + }, + "Box::pin": { + "postfix": "pinbox", + "body": "Box::pin(${receiver})", + "requires": "std::boxed::Box", + "description": "Put the expression into a pinned `Box`", + "scope": "expr" + }, + "Ok": { + "postfix": "ok", + "body": "Ok(${receiver})", + "description": "Wrap the expression in a `Result::Ok`", + "scope": "expr" + }, + "Err": { + "postfix": "err", + "body": "Err(${receiver})", + "description": "Wrap the expression in a `Result::Err`", + "scope": "expr" + }, + "Some": { + "postfix": "some", + "body": "Some(${receiver})", + "description": "Wrap the expression in an `Option::Some`", + "scope": "expr" + } + } + +``` + + Custom completion snippets. + + + **rust-analyzer.diagnostics.disabled** (default: []) + + List of rust-analyzer diagnostics to disable. + + +**rust-analyzer.diagnostics.enable** (default: true) + + Whether to show native rust-analyzer diagnostics. + + +**rust-analyzer.diagnostics.experimental.enable** (default: false) + + Whether to show experimental rust-analyzer diagnostics that might +have more false positives than usual. + + +**rust-analyzer.diagnostics.remapPrefix** (default: {}) + + Map of prefixes to be substituted when parsing diagnostic file paths. +This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`. + + +**rust-analyzer.diagnostics.warningsAsHint** (default: []) + + List of warnings that should be displayed with hint severity. + +The warnings will be indicated by faded text or three dots in code +and will not show up in the `Problems Panel`. + + +**rust-analyzer.diagnostics.warningsAsInfo** (default: []) + + List of warnings that should be displayed with info severity. + +The warnings will be indicated by a blue squiggly underline in code +and a blue icon in the `Problems Panel`. + + +**rust-analyzer.files.excludeDirs** (default: []) + + These directories will be ignored by rust-analyzer. They are +relative to the workspace root, and globs are not supported. You may +also need to add the folders to Code's `files.watcherExclude`. + + +**rust-analyzer.files.watcher** (default: "client") + + Controls file watching implementation. + + +**rust-analyzer.highlightRelated.breakPoints.enable** (default: true) + + Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords. + + +**rust-analyzer.highlightRelated.closureCaptures.enable** (default: true) + + Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure. + + +**rust-analyzer.highlightRelated.exitPoints.enable** (default: true) + + Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`). + + +**rust-analyzer.highlightRelated.references.enable** (default: true) + + Enables highlighting of related references while the cursor is on any identifier. + + +**rust-analyzer.highlightRelated.yieldPoints.enable** (default: true) + + Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords. + + +**rust-analyzer.hover.actions.debug.enable** (default: true) + + Whether to show `Debug` action. Only applies when +`#rust-analyzer.hover.actions.enable#` is set. + + +**rust-analyzer.hover.actions.enable** (default: true) + + Whether to show HoverActions in Rust files. + + +**rust-analyzer.hover.actions.gotoTypeDef.enable** (default: true) + + Whether to show `Go to Type Definition` action. Only applies when +`#rust-analyzer.hover.actions.enable#` is set. + + +**rust-analyzer.hover.actions.implementations.enable** (default: true) + + Whether to show `Implementations` action. Only applies when +`#rust-analyzer.hover.actions.enable#` is set. + + +**rust-analyzer.hover.actions.references.enable** (default: false) + + Whether to show `References` action. Only applies when +`#rust-analyzer.hover.actions.enable#` is set. + + +**rust-analyzer.hover.actions.run.enable** (default: true) + + Whether to show `Run` action. Only applies when +`#rust-analyzer.hover.actions.enable#` is set. + + +**rust-analyzer.hover.documentation.enable** (default: true) + + Whether to show documentation on hover. + + +**rust-analyzer.hover.documentation.keywords.enable** (default: true) + + Whether to show keyword hover popups. Only applies when +`#rust-analyzer.hover.documentation.enable#` is set. + + +**rust-analyzer.hover.links.enable** (default: true) + + Use markdown syntax for links on hover. + + +**rust-analyzer.hover.memoryLayout.alignment** (default: "hexadecimal") + + How to render the align information in a memory layout hover. + + +**rust-analyzer.hover.memoryLayout.enable** (default: true) + + Whether to show memory layout data on hover. + + +**rust-analyzer.hover.memoryLayout.niches** (default: false) + + How to render the niche information in a memory layout hover. + + +**rust-analyzer.hover.memoryLayout.offset** (default: "hexadecimal") + + How to render the offset information in a memory layout hover. + + +**rust-analyzer.hover.memoryLayout.size** (default: "both") + + How to render the size information in a memory layout hover. + + +**rust-analyzer.imports.granularity.enforce** (default: false) + + Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file. + + +**rust-analyzer.imports.granularity.group** (default: "crate") + + How imports should be grouped into use statements. + + +**rust-analyzer.imports.group.enable** (default: true) + + Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines. + + +**rust-analyzer.imports.merge.glob** (default: true) + + Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`. + + +**rust-analyzer.imports.preferNoStd** (default: false) + + Prefer to unconditionally use imports of the core and alloc crate, over the std crate. + + +**rust-analyzer.imports.preferPrelude** (default: false) + + Whether to prefer import paths containing a `prelude` module. + + +**rust-analyzer.imports.prefix** (default: "plain") + + The path structure for newly inserted paths to use. + + +**rust-analyzer.inlayHints.bindingModeHints.enable** (default: false) + + Whether to show inlay type hints for binding modes. + + +**rust-analyzer.inlayHints.chainingHints.enable** (default: true) + + Whether to show inlay type hints for method chains. + + +**rust-analyzer.inlayHints.closingBraceHints.enable** (default: true) + + Whether to show inlay hints after a closing `}` to indicate what item it belongs to. + + +**rust-analyzer.inlayHints.closingBraceHints.minLines** (default: 25) + + Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1 +to always show them). + + +**rust-analyzer.inlayHints.closureCaptureHints.enable** (default: false) + + Whether to show inlay hints for closure captures. + + +**rust-analyzer.inlayHints.closureReturnTypeHints.enable** (default: "never") + + Whether to show inlay type hints for return types of closures. + + +**rust-analyzer.inlayHints.closureStyle** (default: "impl_fn") + + Closure notation in type and chaining inlay hints. + + +**rust-analyzer.inlayHints.discriminantHints.enable** (default: "never") + + Whether to show enum variant discriminant hints. + + +**rust-analyzer.inlayHints.expressionAdjustmentHints.enable** (default: "never") + + Whether to show inlay hints for type adjustments. + + +**rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe** (default: false) + + Whether to hide inlay hints for type adjustments outside of `unsafe` blocks. + + +**rust-analyzer.inlayHints.expressionAdjustmentHints.mode** (default: "prefix") + + Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc). + + +**rust-analyzer.inlayHints.lifetimeElisionHints.enable** (default: "never") + + Whether to show inlay type hints for elided lifetimes in function signatures. + + +**rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames** (default: false) + + Whether to prefer using parameter names as the name for elided lifetime hints if possible. + + +**rust-analyzer.inlayHints.maxLength** (default: 25) + + Maximum length for inlay hints. Set to null to have an unlimited length. + + +**rust-analyzer.inlayHints.parameterHints.enable** (default: true) + + Whether to show function parameter name inlay hints at the call +site. + + +**rust-analyzer.inlayHints.reborrowHints.enable** (default: "never") + + Whether to show inlay hints for compiler inserted reborrows. +This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#. + + +**rust-analyzer.inlayHints.renderColons** (default: true) + + Whether to render leading colons for type hints, and trailing colons for parameter hints. + + +**rust-analyzer.inlayHints.typeHints.enable** (default: true) + + Whether to show inlay type hints for variables. + + +**rust-analyzer.inlayHints.typeHints.hideClosureInitialization** (default: false) + + Whether to hide inlay type hints for `let` statements that initialize to a closure. +Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`. + + +**rust-analyzer.inlayHints.typeHints.hideNamedConstructor** (default: false) + + Whether to hide inlay type hints for constructors. + + +**rust-analyzer.interpret.tests** (default: false) + + Enables the experimental support for interpreting tests. + + +**rust-analyzer.joinLines.joinAssignments** (default: true) + + Join lines merges consecutive declaration and initialization of an assignment. + + +**rust-analyzer.joinLines.joinElseIf** (default: true) + + Join lines inserts else between consecutive ifs. + + +**rust-analyzer.joinLines.removeTrailingComma** (default: true) + + Join lines removes trailing commas. + + +**rust-analyzer.joinLines.unwrapTrivialBlock** (default: true) + + Join lines unwraps trivial blocks. + + +**rust-analyzer.lens.debug.enable** (default: true) + + Whether to show `Debug` lens. Only applies when +`#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.lens.enable** (default: true) + + Whether to show CodeLens in Rust files. + + +**rust-analyzer.lens.forceCustomCommands** (default: true) + + Internal config: use custom client-side commands even when the +client doesn't set the corresponding capability. + + +**rust-analyzer.lens.implementations.enable** (default: true) + + Whether to show `Implementations` lens. Only applies when +`#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.lens.location** (default: "above_name") + + Where to render annotations. + + +**rust-analyzer.lens.references.adt.enable** (default: false) + + Whether to show `References` lens for Struct, Enum, and Union. +Only applies when `#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.lens.references.enumVariant.enable** (default: false) + + Whether to show `References` lens for Enum Variants. +Only applies when `#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.lens.references.method.enable** (default: false) + + Whether to show `Method References` lens. Only applies when +`#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.lens.references.trait.enable** (default: false) + + Whether to show `References` lens for Trait. +Only applies when `#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.lens.run.enable** (default: true) + + Whether to show `Run` lens. Only applies when +`#rust-analyzer.lens.enable#` is set. + + +**rust-analyzer.linkedProjects** (default: []) + + Disable project auto-discovery in favor of explicitly specified set +of projects. + +Elements must be paths pointing to `Cargo.toml`, +`rust-project.json`, or JSON objects in `rust-project.json` format. + + +**rust-analyzer.lru.capacity** (default: null) + + Number of syntax trees rust-analyzer keeps in memory. Defaults to 128. + + +**rust-analyzer.lru.query.capacities** (default: {}) + + Sets the LRU capacity of the specified queries. + + +**rust-analyzer.notifications.cargoTomlNotFound** (default: true) + + Whether to show `can't find Cargo.toml` error message. + + +**rust-analyzer.numThreads** (default: null) + + How many worker threads in the main loop. The default `null` means to pick automatically. + + +**rust-analyzer.procMacro.attributes.enable** (default: true) + + Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. + + +**rust-analyzer.procMacro.enable** (default: true) + + Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. + + +**rust-analyzer.procMacro.ignored** (default: {}) + + These proc-macros will be ignored when trying to expand them. + +This config takes a map of crate names with the exported proc-macro names to ignore as values. + + +**rust-analyzer.procMacro.server** (default: null) + + Internal config, path to proc-macro server executable. + + +**rust-analyzer.references.excludeImports** (default: false) + + Exclude imports from find-all-references. + + +**rust-analyzer.runnables.command** (default: null) + + Command to be executed instead of 'cargo' for runnables. + + +**rust-analyzer.runnables.extraArgs** (default: []) + + Additional arguments to be passed to cargo for runnables such as +tests or binaries. For example, it may be `--release`. + + +**rust-analyzer.rust.analyzerTargetDir** (default: null) + + Optional path to a rust-analyzer specific target directory. +This prevents rust-analyzer's `cargo check` 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. + + +**rust-analyzer.rustc.source** (default: null) + + Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private +projects, or "discover" to try to automatically find it if the `rustc-dev` component +is installed. + +Any project which uses rust-analyzer with the rustcPrivate +crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. + +This option does not take effect until rust-analyzer is restarted. + + +**rust-analyzer.rustfmt.extraArgs** (default: []) + + Additional arguments to `rustfmt`. + + +**rust-analyzer.rustfmt.overrideCommand** (default: null) + + Advanced option, fully override the command rust-analyzer uses for +formatting. This should be the equivalent of `rustfmt` here, and +not that of `cargo fmt`. The file contents will be passed on the +standard input and the formatted result will be read from the +standard output. + + +**rust-analyzer.rustfmt.rangeFormatting.enable** (default: false) + + Enables the use of rustfmt's unstable range formatting command for the +`textDocument/rangeFormatting` request. The rustfmt option is unstable and only +available on a nightly build. + + +**rust-analyzer.semanticHighlighting.doc.comment.inject.enable** (default: true) + + Inject additional highlighting into doc comments. + +When enabled, rust-analyzer will highlight rust source in doc comments as well as intra +doc links. + + +**rust-analyzer.semanticHighlighting.nonStandardTokens** (default: true) + + Whether the server is allowed to emit non-standard tokens and modifiers. + + +**rust-analyzer.semanticHighlighting.operator.enable** (default: true) + + Use semantic tokens for operators. + +When disabled, rust-analyzer will emit semantic tokens only for operator tokens when +they are tagged with modifiers. + + +**rust-analyzer.semanticHighlighting.operator.specialization.enable** (default: false) + + Use specialized semantic tokens for operators. + +When enabled, rust-analyzer will emit special token types for operator tokens instead +of the generic `operator` token type. + + +**rust-analyzer.semanticHighlighting.punctuation.enable** (default: false) + + Use semantic tokens for punctuation. + +When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when +they are tagged with modifiers or have a special role. + + +**rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang** (default: false) + + When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro +calls. + + +**rust-analyzer.semanticHighlighting.punctuation.specialization.enable** (default: false) + + Use specialized semantic tokens for punctuation. + +When enabled, rust-analyzer will emit special token types for punctuation tokens instead +of the generic `punctuation` token type. + + +**rust-analyzer.semanticHighlighting.strings.enable** (default: true) + + Use semantic tokens for strings. + +In some editors (e.g. vscode) semantic tokens override other highlighting grammars. +By disabling semantic tokens for strings, other grammars can be used to highlight +their contents. + + +**rust-analyzer.signatureInfo.detail** (default: "full") + + Show full signature of the callable. Only shows parameters if disabled. + + +**rust-analyzer.signatureInfo.documentation.enable** (default: true) + + Show documentation. + + +**rust-analyzer.typing.autoClosingAngleBrackets.enable** (default: false) + + Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list. + + +**rust-analyzer.workspace.symbol.search.kind** (default: "only_types") + + Workspace symbol search kind. + + +**rust-analyzer.workspace.symbol.search.limit** (default: 128) + + Limits the number of items returned from a workspace symbol search (Defaults to 128). +Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search. +Other clients requires all results upfront and might require a higher limit. + + +**rust-analyzer.workspace.symbol.search.scope** (default: "workspace") + + Workspace symbol search scope. + + diff --git a/docs/book/src/diagnostics/README.md b/docs/book/src/diagnostics/README.md new file mode 100644 index 000000000000..90d90da65725 --- /dev/null +++ b/docs/book/src/diagnostics/README.md @@ -0,0 +1,16 @@ +# Diagnostics + +While most errors and warnings provided by rust-analyzer come from the +`cargo check` integration, there’s a growing number of diagnostics +implemented using rust-analyzer’s own analysis. Some of these +diagnostics don’t respect `#[allow]` or `\#[deny]` attributes yet, but +can be turned off using the `rust-analyzer.diagnostics.enable`, +`rust-analyzer.diagnostics.experimental.enable` or +`rust-analyzer.diagnostics.disabled` settings. + +## Clippy + +To run `cargo clippy` instead of `cargo check`, you can set +`"rust-analyzer.check.command": "clippy"`. + +{{#include generated.md:2:}} diff --git a/docs/book/src/diagnostics/generated.md b/docs/book/src/diagnostics/generated.md new file mode 100644 index 000000000000..6dfafad88d17 --- /dev/null +++ b/docs/book/src/diagnostics/generated.md @@ -0,0 +1,378 @@ +//! Generated by `sourcegen_diagnostic_docs`, do not edit by hand. + +#### break-outside-of-loop + +Source: [break_outside_of_loop.rs](crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs#3) + + +This diagnostic is triggered if the `break` keyword is used outside of a loop. + + + + +#### expected-function + +Source: [expected_function.rs](crates/ide-diagnostics/src/handlers/expected_function.rs#5) + + +This diagnostic is triggered if a call is made on something that is not callable. + + + + +#### inactive-code + +Source: [inactive_code.rs](crates/ide-diagnostics/src/handlers/inactive_code.rs#6) + + +This diagnostic is shown for code with inactive `#[cfg]` attributes. + + + + +#### incoherent-impl + +Source: [incoherent_impl.rs](crates/ide-diagnostics/src/handlers/incoherent_impl.rs#5) + + +This diagnostic is triggered if the targe type of an impl is from a foreign crate. + + + + +#### incorrect-ident-case + +Source: [incorrect_case.rs](crates/ide-diagnostics/src/handlers/incorrect_case.rs#13) + + +This diagnostic is triggered if an item name doesn't follow [Rust naming convention](https://doc.rust-lang.org/1.0.0/style/style/naming/README.html). + + + + +#### invalid-derive-target + +Source: [invalid_derive_target.rs](crates/ide-diagnostics/src/handlers/invalid_derive_target.rs#3) + + +This diagnostic is shown when the derive attribute is used on an item other than a `struct`, +`enum` or `union`. + + + + +#### macro-error + +Source: [macro_error.rs](crates/ide-diagnostics/src/handlers/macro_error.rs#3) + + +This diagnostic is shown for macro expansion errors. + + + + +#### macro-error + +Source: [macro_error.rs](crates/ide-diagnostics/src/handlers/macro_error.rs#17) + + +This diagnostic is shown for macro expansion errors. + + + + +#### malformed-derive + +Source: [malformed_derive.rs](crates/ide-diagnostics/src/handlers/malformed_derive.rs#3) + + +This diagnostic is shown when the derive attribute has invalid input. + + + + +#### mismatched-arg-count + +Source: [mismatched_arg_count.rs](crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs#30) + + +This diagnostic is triggered if a function is invoked with an incorrect amount of arguments. + + + + +#### mismatched-tuple-struct-pat-arg-count + +Source: [mismatched_arg_count.rs](crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs#10) + + +This diagnostic is triggered if a function is invoked with an incorrect amount of arguments. + + + + +#### missing-fields + +Source: [missing_fields.rs](crates/ide-diagnostics/src/handlers/missing_fields.rs#20) + + +This diagnostic is triggered if record lacks some fields that exist in the corresponding structure. + +Example: + +```rust +struct A { a: u8, b: u8 } + +let a = A { a: 10 }; +``` + + + + +#### missing-match-arm + +Source: [missing_match_arms.rs](crates/ide-diagnostics/src/handlers/missing_match_arms.rs#3) + + +This diagnostic is triggered if `match` block is missing one or more match arms. + + + + +#### missing-unsafe + +Source: [missing_unsafe.rs](crates/ide-diagnostics/src/handlers/missing_unsafe.rs#9) + + +This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block. + + + + +#### moved-out-of-ref + +Source: [moved_out_of_ref.rs](crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs#4) + + +This diagnostic is triggered on moving non copy things out of references. + + + + +#### need-mut + +Source: [mutability_errors.rs](crates/ide-diagnostics/src/handlers/mutability_errors.rs#7) + + +This diagnostic is triggered on mutating an immutable variable. + + + + +#### no-such-field + +Source: [no_such_field.rs](crates/ide-diagnostics/src/handlers/no_such_field.rs#12) + + +This diagnostic is triggered if created structure does not have field provided in record. + + + + +#### private-assoc-item + +Source: [private_assoc_item.rs](crates/ide-diagnostics/src/handlers/private_assoc_item.rs#3) + + +This diagnostic is triggered if the referenced associated item is not visible from the current +module. + + + + +#### private-field + +Source: [private_field.rs](crates/ide-diagnostics/src/handlers/private_field.rs#3) + + +This diagnostic is triggered if the accessed field is not visible from the current module. + + + + +#### replace-filter-map-next-with-find-map + +Source: [replace_filter_map_next_with_find_map.rs](crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs#11) + + +This diagnostic is triggered when `.filter_map(..).next()` is used, rather than the more concise `.find_map(..)`. + + + + +#### type-mismatch + +Source: [type_mismatch.rs](crates/ide-diagnostics/src/handlers/type_mismatch.rs#11) + + +This diagnostic is triggered when the type of an expression or pattern does not match +the expected type. + + + + +#### typed-hole + +Source: [typed_hole.rs](crates/ide-diagnostics/src/handlers/typed_hole.rs#12) + + +This diagnostic is triggered when an underscore expression is used in an invalid position. + + + + +#### undeclared-label + +Source: [undeclared_label.rs](crates/ide-diagnostics/src/handlers/undeclared_label.rs#3) + + + + + + +#### unimplemented-builtin-macro + +Source: [unimplemented_builtin_macro.rs](crates/ide-diagnostics/src/handlers/unimplemented_builtin_macro.rs#3) + + +This diagnostic is shown for builtin macros which are not yet implemented by rust-analyzer + + + + +#### unlinked-file + +Source: [unlinked_file.rs](crates/ide-diagnostics/src/handlers/unlinked_file.rs#19) + + +This diagnostic is shown for files that are not included in any crate, or files that are part of +crates rust-analyzer failed to discover. The file will not have IDE features available. + + + + +#### unnecessary-braces + +Source: [useless_braces.rs](crates/ide-diagnostics/src/handlers/useless_braces.rs#9) + + +Diagnostic for unnecessary braces in `use` items. + + + + +#### unreachable-label + +Source: [unreachable_label.rs](crates/ide-diagnostics/src/handlers/unreachable_label.rs#3) + + + + + + +#### unresolved-extern-crate + +Source: [unresolved_extern_crate.rs](crates/ide-diagnostics/src/handlers/unresolved_extern_crate.rs#3) + + +This diagnostic is triggered if rust-analyzer is unable to discover referred extern crate. + + + + +#### unresolved-field + +Source: [unresolved_field.rs](crates/ide-diagnostics/src/handlers/unresolved_field.rs#13) + + +This diagnostic is triggered if a field does not exist on a given type. + + + + +#### unresolved-import + +Source: [unresolved_import.rs](crates/ide-diagnostics/src/handlers/unresolved_import.rs#3) + + +This diagnostic is triggered if rust-analyzer is unable to resolve a path in +a `use` declaration. + + + + +#### unresolved-macro-call + +Source: [unresolved_macro_call.rs](crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs#3) + + +This diagnostic is triggered if rust-analyzer is unable to resolve the path +to a macro in a macro invocation. + + + + +#### unresolved-method + +Source: [unresolved_method.rs](crates/ide-diagnostics/src/handlers/unresolved_method.rs#13) + + +This diagnostic is triggered if a method does not exist on a given type. + + + + +#### unresolved-module + +Source: [unresolved_module.rs](crates/ide-diagnostics/src/handlers/unresolved_module.rs#8) + + +This diagnostic is triggered if rust-analyzer is unable to discover referred module. + + + + +#### unresolved-proc-macro + +Source: [unresolved_proc_macro.rs](crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs#5) + + +This diagnostic is shown when a procedural macro can not be found. This usually means that +procedural macro support is simply disabled (and hence is only a weak hint instead of an error), +but can also indicate project setup problems. + +If you are seeing a lot of "proc macro not expanded" warnings, you can add this option to the +`rust-analyzer.diagnostics.disabled` list to prevent them from showing. Alternatively you can +enable support for procedural macros (see `rust-analyzer.procMacro.attributes.enable`). + + + + +#### unused-mut + +Source: [mutability_errors.rs](crates/ide-diagnostics/src/handlers/mutability_errors.rs#45) + + +This diagnostic is triggered when a mutable variable isn't actually mutated. + + + + +#### unused-variables + +Source: [unused_variables.rs](crates/ide-diagnostics/src/handlers/unused_variables.rs#3) + + +This diagnostic is triggered when a local variable is not used. + + diff --git a/docs/book/src/editor_features/README.md b/docs/book/src/editor_features/README.md new file mode 100644 index 000000000000..8ec05b9a3afb --- /dev/null +++ b/docs/book/src/editor_features/README.md @@ -0,0 +1,186 @@ +# Editor Features + + +## VS Code + +### Color configurations + +It is possible to change the foreground/background color and font +family/size of inlay hints. Just add this to your `settings.json`: + + { + "editor.inlayHints.fontFamily": "Courier New", + "editor.inlayHints.fontSize": 11, + + "workbench.colorCustomizations": { + // Name of the theme you are currently using + "[Default Dark+]": { + "editorInlayHint.foreground": "#868686f0", + "editorInlayHint.background": "#3d3d3d48", + + // Overrides for specific kinds of inlay hints + "editorInlayHint.typeForeground": "#fdb6fdf0", + "editorInlayHint.parameterForeground": "#fdb6fdf0", + } + } + } + +### Semantic style customizations + +You can customize the look of different semantic elements in the source +code. For example, mutable bindings are underlined by default and you +can override this behavior by adding the following section to your +`settings.json`: + + { + "editor.semanticTokenColorCustomizations": { + "rules": { + "*.mutable": { + "fontStyle": "", // underline is the default + }, + } + }, + } + +Most themes doesn’t support styling unsafe operations differently yet. +You can fix this by adding overrides for the rules `operator.unsafe`, +`function.unsafe`, and `method.unsafe`: + + { + "editor.semanticTokenColorCustomizations": { + "rules": { + "operator.unsafe": "#ff6600", + "function.unsafe": "#ff6600", + "method.unsafe": "#ff6600" + } + }, + } + +In addition to the top-level rules you can specify overrides for +specific themes. For example, if you wanted to use a darker text color +on a specific light theme, you might write: + + { + "editor.semanticTokenColorCustomizations": { + "rules": { + "operator.unsafe": "#ff6600" + }, + "[Ayu Light]": { + "rules": { + "operator.unsafe": "#572300" + } + } + }, + } + +Make sure you include the brackets around the theme name. For example, +use `"[Ayu Light]"` to customize the theme Ayu Light. + +### Special `when` clause context for keybindings. + +You may use `inRustProject` context to configure keybindings for rust +projects only. For example: + + { + "key": "ctrl+alt+d", + "command": "rust-analyzer.openDocs", + "when": "inRustProject" + } + +More about `when` clause contexts +[here](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts). + +### Setting runnable environment variables + +You can use "rust-analyzer.runnables.extraEnv" setting to define +runnable environment-specific substitution variables. The simplest way +for all runnables in a bunch: + + "rust-analyzer.runnables.extraEnv": { + "RUN_SLOW_TESTS": "1" + } + +Or it is possible to specify vars more granularly: + + "rust-analyzer.runnables.extraEnv": [ + { + // "mask": null, // null mask means that this rule will be applied for all runnables + env: { + "APP_ID": "1", + "APP_DATA": "asdf" + } + }, + { + "mask": "test_name", + "env": { + "APP_ID": "2", // overwrites only APP_ID + } + } + ] + +You can use any valid regular expression as a mask. Also note that a +full runnable name is something like **run bin\_or\_example\_name**, +**test some::mod::test\_name** or **test-mod some::mod**, so it is +possible to distinguish binaries, single tests, and test modules with +this masks: `"^run"`, `"^test "` (the trailing space matters!), and +`"^test-mod"` respectively. + +If needed, you can set different values for different platforms: + + "rust-analyzer.runnables.extraEnv": [ + { + "platform": "win32", // windows only + env: { + "APP_DATA": "windows specific data" + } + }, + { + "platform": ["linux"], + "env": { + "APP_DATA": "linux data", + } + }, + { // for all platforms + "env": { + "APP_COMMON_DATA": "xxx", + } + } + ] + +### Compiler feedback from external commands + +Instead of relying on the built-in `cargo check`, you can configure Code +to run a command in the background and use the `$rustc-watch` problem +matcher to generate inline error markers from its output. + +To do this you need to create a new [VS Code +Task](https://code.visualstudio.com/docs/editor/tasks) and set +`"rust-analyzer.checkOnSave": false` in preferences. + +For example, if you want to run +[`cargo watch`](https://crates.io/crates/cargo-watch) instead, you might +add the following to `.vscode/tasks.json`: + + { + "label": "Watch", + "group": "build", + "type": "shell", + "command": "cargo watch", + "problemMatcher": "$rustc-watch", + "isBackground": true + } + +### Live Share + +VS Code Live Share has partial support for rust-analyzer. + +Live Share *requires* the official Microsoft build of VS Code, OSS +builds will not work correctly. + +The host’s rust-analyzer instance will be shared with all guests joining +the session. The guests do not have to have the rust-analyzer extension +installed for this to work. + +If you are joining a Live Share session and *do* have rust-analyzer +installed locally, commands from the command palette will not work +correctly since they will attempt to communicate with the local server. diff --git a/docs/book/src/features/README.md b/docs/book/src/features/README.md new file mode 100644 index 000000000000..96ae4ac8b7d9 --- /dev/null +++ b/docs/book/src/features/README.md @@ -0,0 +1,3 @@ +# Features + +{{#include generated.md:3:}} diff --git a/docs/book/src/features/generated.md b/docs/book/src/features/generated.md new file mode 100644 index 000000000000..1abd62e82102 --- /dev/null +++ b/docs/book/src/features/generated.md @@ -0,0 +1,929 @@ + +// Generated file, do not edit by hand, see `sourcegen_feature_docs`. +### Annotations +**Source:** [annotations.rs](crates/ide/src/annotations.rs#20) + +Provides user with annotations above items for looking up references or impl blocks +and running/debugging binaries. + +![Annotations](https://user-images.githubusercontent.com/48062697/113020672-b7c34f00-917a-11eb-8f6e-858735660a0e.png) + + +### Auto Import +**Source:** [auto_import.rs](crates/ide-assists/src/handlers/auto_import.rs#15) + +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` and `core` +- External Crates +- Current Crate, paths prefixed by `crate` +- Current Module, paths prefixed by `self` +- Super Module, paths prefixed by `super` + +Example: +```rust +use std::fs::File; + +use itertools::Itertools; +use syntax::ast; + +use crate::utils::insert_use; + +use self::auto_import; + +use super::AssistContext; +``` + +#### Import Granularity + +It is possible to configure how use-trees are merged with the `imports.granularity.group` 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 as `item`. + +In `VS Code` the configuration for this is `rust-analyzer.imports.granularity.group`. + +#### Import Prefix + +The style of imports in the same crate is configurable through the `imports.prefix` setting. +It has the following configurations: + +- `crate`: This setting will force paths to be always absolute, starting with the `crate` + prefix, unless the item is defined outside of the current crate. +- `self`: This setting will force paths that are relative to the current module to always + start with `self`. This will result in paths that always start with either `crate`, `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.imports.prefix`. + +![Auto Import](https://user-images.githubusercontent.com/48062697/113020673-b85be580-917a-11eb-9022-59585f35d4f8.gif) + + +### Completion With Autoimport +**Source:** [flyimport.rs](crates/ide-completion/src/completions/flyimport.rs#19) + +When completing names in the current scope, proposes additional imports from other modules or crates, +if they can be qualified in the scope, and their name contains all symbols from the completion input. + +To be considered applicable, the name must contain all input symbols in the given order, not necessarily adjacent. +If any input symbol is not lowercased, the name must contain all symbols in exact case; otherwise the containing is checked case-insensitively. + +``` +fn main() { + pda$0 +} +# pub mod std { pub mod marker { pub struct PhantomData { } } } +``` +-> +``` +use std::marker::PhantomData; + +fn main() { + PhantomData +} +# pub mod std { pub mod marker { pub struct PhantomData { } } } +``` + +Also completes associated items, that require trait imports. +If any unresolved and/or partially-qualified path precedes the input, it will be taken into account. +Currently, only the imports with their import path ending with the whole qualifier will be proposed +(no fuzzy matching for qualifier). + +``` +mod foo { + pub mod bar { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } + } +} + +fn main() { + bar::Item::TEST_A$0 +} +``` +-> +``` +use foo::bar; + +mod foo { + pub mod bar { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } + } +} + +fn main() { + bar::Item::TEST_ASSOC +} +``` + +NOTE: currently, if an assoc item comes from a trait that's not currently imported, and it also has an unresolved and/or partially-qualified path, +no imports will be proposed. + +#### Fuzzy search details + +To avoid an excessive amount of the results returned, completion input is checked for inclusion in the names only +(i.e. in `HashMap` in the `std::collections::HashMap` path). +For the same reasons, avoids searching for any path imports for inputs with their length less than 2 symbols +(but shows all associated items for any input length). + +#### Import configuration + +It is possible to configure how use-trees are merged with the `imports.granularity.group` setting. +Mimics the corresponding behavior of the `Auto Import` feature. + +#### LSP and performance implications + +The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits` +(case-sensitive) resolve client capability in its client capabilities. +This way the server is able to defer the costly computations, doing them for a selected completion item only. +For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones, +which might be slow ergo the feature is automatically disabled. + +#### Feature toggle + +The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.autoimport.enable` flag. +Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corresponding +capability enabled. + + +### Debug ItemTree +**Source:** [view_item_tree.rs](crates/ide/src/view_item_tree.rs#5) + +Displays the ItemTree of the currently open file, for debugging. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Debug ItemTree** | + + +### Expand Macro Recursively +**Source:** [expand_macro.rs](crates/ide/src/expand_macro.rs#15) + +Shows the full macro expansion of the macro at the current caret position. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Expand macro recursively** | + +![Expand Macro Recursively](https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif) + + +### Expand and Shrink Selection +**Source:** [extend_selection.rs](crates/ide/src/extend_selection.rs#15) + +Extends or shrinks the current selection to the encompassing syntactic construct +(expression, statement, item, module, etc). It works with multiple cursors. + +| Editor | Shortcut | +|---------|----------| +| VS Code | Alt+Shift+→, Alt+Shift+← | + +![Expand and Shrink Selection](https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif) + + +### File Structure +**Source:** [file_structure.rs](crates/ide/src/file_structure.rs#25) + +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 | Ctrl+Shift+O | + +![File Structure](https://user-images.githubusercontent.com/48062697/113020654-b42fc800-917a-11eb-8388-e7dc4d92b02e.gif) + + +### Find All References +**Source:** [references.rs](crates/ide/src/references.rs#43) + +Shows all references of the item at the cursor location + +| Editor | Shortcut | +|---------|----------| +| VS Code | Shift+Alt+F12 | + +![Find All References](https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif) + + +### Folding +**Source:** [folding_ranges.rs](crates/ide/src/folding_ranges.rs#36) + +Defines folding regions for curly braced blocks, runs of consecutive use, mod, const or static +items, and `region` / `endregion` comment markers. + + +### Format String Completion +**Source:** [format_like.rs](crates/ide-completion/src/completions/postfix/format_like.rs#0) + +`"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!(...)` + +![Format String Completion](https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif) + + +### Go to Declaration +**Source:** [goto_declaration.rs](crates/ide/src/goto_declaration.rs#13) + +Navigates to the declaration of an identifier. + +This is the same as `Go to Definition` with the following exceptions: +- outline modules will navigate to the `mod name;` item declaration +- trait assoc items will navigate to the assoc item of the trait declaration opposed to the trait impl +- fields in patterns will navigate to the field declaration of the struct, union or variant + + +### Go to Definition +**Source:** [goto_definition.rs](crates/ide/src/goto_definition.rs#17) + +Navigates to the definition of an identifier. + +For outline modules, this will navigate to the source file of the module. + +| Editor | Shortcut | +|---------|----------| +| VS Code | F12 | + +![Go to Definition](https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif) + + +### Go to Implementation +**Source:** [goto_implementation.rs](crates/ide/src/goto_implementation.rs#12) + +Navigates to the impl blocks of types. + +| Editor | Shortcut | +|---------|----------| +| VS Code | Ctrl+F12 + +![Go to Implementation](https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif) + + +### Go to Type Definition +**Source:** [goto_type_definition.rs](crates/ide/src/goto_type_definition.rs#6) + +Navigates to the type of an identifier. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **Go to Type Definition** | + +![Go to Type Definition](https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif) + + +### Highlight Related +**Source:** [highlight_related.rs](crates/ide/src/highlight_related.rs#40) + +Highlights constructs related to the thing under the cursor: + +. if on an identifier, highlights all references to that identifier in the current file +.. additionally, if the identifier is a trait in a where clause, type parameter trait bound or use item, highlights all references to that trait's assoc items in the corresponding scope +. if on an `async` or `await token, highlights all yield points for that async context +. if on a `return` or `fn` keyword, `?` 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 +. if on a `move` or `|` token that belongs to a closure, highlights all captures of the closure. + +Note: `?`, `|` and `->` do not currently trigger this behavior in the VSCode editor. + + +### Hover +**Source:** [hover.rs](crates/ide/src/hover.rs#97) + +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. + +![Hover](https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif) + + +### Inlay Hints +**Source:** [inlay_hints.rs](crates/ide/src/inlay_hints.rs#421) + +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 by default shows hints for + +* types of local variables +* names of function arguments +* types of chained expressions + +Optionally, one can enable additional hints for + +* return types of closure expressions +* elided lifetimes +* compiler inserted reborrows + +![Hover](https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png) + + +### Interpret Function +**Source:** [interpret_function.rs](crates/ide/src/interpret_function.rs#9) + +| Editor | Action Name | +|---------|--------------| +| VS Code | **rust-analyzer: Interpret Function** | + + +### Join Lines +**Source:** [join_lines.rs](crates/ide/src/join_lines.rs#20) + +Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces. + +See [this gif](img/features/join_lines-1.gif) for the cases handled specially by joined lines. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Join lines** | + +![Join Lines](https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif) + + +### Magic Completions +**Source:** [lib.rs](crates/ide-completion/src/lib.rs#45) + +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.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: + +#### Expressions + +- `pd` -> `eprintln!(" = {:?}", );` +- `ppd` -> `eprintln!(" = {:#?}", );` + +#### Items + +- `tfn` -> `#[test] fn feature(){}` +- `tmod` -> +```rust +#[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. + +![Magic Completions](https://user-images.githubusercontent.com/48062697/113020667-b72ab880-917a-11eb-8778-716cf26a0eb3.gif) + + +### Matching Brace +**Source:** [matching_brace.rs](crates/ide/src/matching_brace.rs#6) + +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** | + +![Matching Brace](https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif) + + +### Memory Usage +**Source:** [apply_change.rs](crates/ide-db/src/apply_change.rs#43) + +Clears rust-analyzer's internal database and prints memory usage statistics. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Memory Usage (Clears Database)** + + +### Move Item +**Source:** [move_item.rs](crates/ide/src/move_item.rs#15) + +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** + +![Move Item](https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif) + + +### On Enter +**Source:** [on_enter.rs](crates/ide/src/typing/on_enter.rs#16) + +rust-analyzer can override kbd:[Enter] key to make it smarter: + +- Enter inside triple-slash comments automatically inserts `///` +- Enter in the middle or after a trailing space in `//` inserts `//` +- Enter inside `//!` doc comments automatically inserts `//!` +- Enter after `{` indents contents and closing `}` of single-line block + +This action needs to be assigned to shortcut explicitly. + +Note that, depending on the other installed extensions, this feature can visibly slow down typing. +Similarly, if rust-analyzer crashes or stops responding, `Enter` might not work. +In that case, you can still press `Shift-Enter` to insert a newline. + +VS Code:: + +Add the following to `keybindings.json`: +```json +{ + "key": "Enter", + "command": "rust-analyzer.onEnter", + "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust" +} +```` + +When using the Vim plugin: +```json +{ + "key": "Enter", + "command": "rust-analyzer.onEnter", + "when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust && vim.mode == 'Insert'" +} +```` + +![On Enter](https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif) + + +### On Typing Assists +**Source:** [typing.rs](crates/ide/src/typing.rs#42) + +Some features trigger on typing certain characters: + +- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression +- typing `=` between two expressions adds `;` when in statement position +- typing `=` to turn an assignment into an equality comparison removes `;` when in expression position +- typing `.` in a chain method call auto-indents +- typing `{` or `(` in front of an expression inserts a closing `}` or `)` after the expression +- typing `{` in a use item adds a closing `}` in the right place + +VS Code:: + +Add the following to `settings.json`: +```json +"editor.formatOnType": true, +``` + +![On Typing Assists](https://user-images.githubusercontent.com/48062697/113166163-69758500-923a-11eb-81ee-eb33ec380399.gif) +![On Typing Assists](https://user-images.githubusercontent.com/48062697/113171066-105c2000-923f-11eb-87ab-f4a263346567.gif) + + +### Open Docs +**Source:** [doc_links.rs](crates/ide/src/doc_links.rs#121) + +Retrieve a links to documentation for the given symbol. + +The simplest way to use this feature is via the context menu. Right-click on +the selected item. The context menu opens. Select **Open Docs**. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Open Docs** | + + +### Parent Module +**Source:** [parent_module.rs](crates/ide/src/parent_module.rs#14) + +Navigates to the parent module of the current module. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Locate parent module** | + +![Parent Module](https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif) + + +### Related Tests +**Source:** [runnables.rs](crates/ide/src/runnables.rs#194) + +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** | + + +### Rename +**Source:** [rename.rs](crates/ide/src/rename.rs#73) + +Renames the item below the cursor and all of its references + +| Editor | Shortcut | +|---------|----------| +| VS Code | F2 | + +![Rename](https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif) + + +### Run +**Source:** [runnables.rs](crates/ide/src/runnables.rs#111) + +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** | + +![Run](https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif) + + +### Semantic Syntax Highlighting +**Source:** [syntax_highlighting.rs](crates/ide/src/syntax_highlighting.rs#65) + +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. + + +#### Token Tags + +Rust-analyzer currently emits the following token tags: + +- For items: + +| | | +|-----------|--------------------------------| +| attribute | Emitted for attribute macros. | +|enum| Emitted for enums. | +|function| Emitted for free-standing functions. | +|derive| Emitted for derive macros. | +|macro| Emitted for function-like 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` and `false`.| +| 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 `{:?}` in `format!`-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 oerators `>`, `<`, `==`, `>=`, `<=`, `!=`.| +|logical| Emitted for the logical operatos `||`, `&&`, `!`.| + +- For punctuation: + +| | | +|-----------|--------------------------------| +|punctuation| Emitted for general punctuation.| +|attributeBracket| Emitted for attribute invocation brackets, that is the `#[` and `]` tokens.| +|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.| +|macroBang| Emitted for the `!` token in macro calls.| + +- + +| | | +|-----------|--------------------------------| +|builtinAttribute| Emitted for names to builtin attributes in attribute path, the `repr` in `#[repr(u8)]` for example.| +|builtinType| Emitted for builtin types like `u32`, `str` and `f32`.| +|comment| Emitted for comments.| +|constParameter| Emitted for const parameters.| +|deriveHelper| Emitted for derive helper attributes.| +|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.| +|selfTypeKeyword| Emitted for the Self type parameter.| +|toolModule| Emitted for tool modules.| +|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 + +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 `async` and `await` keywords.| +|attribute| Emitted for tokens inside attributes.| +|callable| Emitted for locals whose types implements one of the `Fn*` taits.| +|constant| Emitted for const.| +|consuming| Emitted for locals that are being consumed when use in a fuction call.| +|controlFlow| Emitted for control-flow related tokens, this includes th `?` operator.| +|crateRoot| Emitted for crate names, like `serde` and `crate.| +|declaration| Emitted for names of definitions, like `foo` in `fn foo(){}`.| +|defaultLibrary| Emitted for items from built-in crates (std, core, allc, test and proc_macro).| +|documentation| Emitted for documentation comment.| +|injected| Emitted for doc-string injected highlighting like rust sourc blocks in documentation.| +|intraDocLink| Emitted for intra doc links in doc-string.| +|library| Emitted for items that are defined outside of the current crae.| +|macro| Emitted for tokens inside macro call.| +|mutable| Emitted for mutable locals and statics as well as functions tking `&mut self`.| +|public| Emitted for items that are from the current crate and are `pub.| +|reference| Emitted for locals behind a reference and functions taking self` by reference.| +|static| Emitted for "static" functions, also known as functions that d not take a `self` param, as well as statics and consts.| +|trait| Emitted for associated trait item.| +|unsafe| Emitted for unsafe operations, like unsafe function calls, as ell as the `unsafe` token.| + +![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png) +![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png) + + +### Show Dependency Tree +**Source:** [fetch_crates.rs](crates/ide/src/fetch_crates.rs#13) + +Shows a view tree with all the dependencies of this project + +| Editor | Panel Name | +|---------|------------| +| VS Code | **Rust Dependencies** | + +![Show Dependency Tree](https://user-images.githubusercontent.com/5748995/229394139-2625beab-f4c9-484b-84ed-ad5dee0b1e1a.png) + + +### Show Syntax Tree +**Source:** [syntax_tree.rs](crates/ide/src/syntax_tree.rs#9) + +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** | + +![Show Syntax Tree](https://user-images.githubusercontent.com/48062697/113065586-068bdb80-91b1-11eb-9507-fee67f9f45a0.gif) + + +### Shuffle Crate Graph +**Source:** [shuffle_crate_graph.rs](crates/ide/src/shuffle_crate_graph.rs#7) + +Randomizes all crate IDs in the crate graph, for debugging. + +| Editor | Action Name | +|---------|--------------| +| VS Code | **rust-analyzer: Shuffle Crate Graph** | + + +### Status +**Source:** [status.rs](crates/ide/src/status.rs#28) + +Shows internal statistic about memory usage of rust-analyzer. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: Status** | + +![Status](https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif) + + +### Structural Search and Replace +**Source:** [lib.rs](crates/ide-ssr/src/lib.rs#8) + +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 ` ==>> `. +A `$` placeholder in the search pattern will match any AST node and `$` 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 `${::...}`. + +Supported constraints: + +| Constraint | Restricts placeholder | +|---------------|------------------------| +| kind(literal) | Is a literal (e.g. `42` or `"forty two"`) | +| not(a) | Negates the constraint `a` | + +Available via the command `rust-analyzer.ssr`. + +```rust +// 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. + +```rust +// Place the cursor on the line below to see the assist 💡. +// foo($a, $b) ==>> ($a).foo($b) +``` + + +### User Snippet Completions +**Source:** [snippet.rs](crates/ide-completion/src/snippet.rs#5) + +rust-analyzer allows the user to define custom (postfix)-snippets that may depend on items to be accessible for the current scope to be applicable. + +A custom snippet can be defined by adding it to the `rust-analyzer.completion.snippets.custom` object respectively. + +```json +{ + "rust-analyzer.completion.snippets.custom": { + "thread spawn": { + "prefix": ["spawn", "tspawn"], + "body": [ + "thread::spawn(move || {", + "\t$0", + "});", + ], + "description": "Insert a thread::spawn call", + "requires": "std::thread", + "scope": "expr", + } + } +} +``` + +In the example above: + +* `"thread spawn"` is the name of the snippet. + +* `prefix` defines one or more trigger words that will trigger the snippets completion. +Using `postfix` will instead create a postfix snippet. + +* `body` is one or more lines of content joined via newlines for the final output. + +* `description` is an optional description of the snippet, if unset the snippet name will be used. + +* `requires` is an optional list of item paths that have to be resolvable in the current crate where the completion is rendered. + + +### View Crate Graph +**Source:** [view_crate_graph.rs](crates/ide/src/view_crate_graph.rs#8) + +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** | + + +### View Hir +**Source:** [view_hir.rs](crates/ide/src/view_hir.rs#6) + +| Editor | Action Name | +|---------|--------------| +| VS Code | **rust-analyzer: View Hir** + +![View Hir](https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif) + + +### View Memory Layout +**Source:** [view_memory_layout.rs](crates/ide/src/view_memory_layout.rs#77) + +Displays the recursive memory layout of a datatype. + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: View Memory Layout** | + + +### View Mir +**Source:** [view_mir.rs](crates/ide/src/view_mir.rs#6) + +| Editor | Action Name | +|---------|-------------| +| VS Code | **rust-analyzer: View Mir** + + +### Workspace Symbol +**Source:** [symbol_index.rs](crates/ide-db/src/symbol_index.rs#181) + +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. + +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 | Ctrl+T diff --git a/docs/book/src/installation/README.md b/docs/book/src/installation/README.md new file mode 100644 index 000000000000..1c1b28b83964 --- /dev/null +++ b/docs/book/src/installation/README.md @@ -0,0 +1,635 @@ +# Installation + +In theory, one should be able to just install the [`rust-analyzer` +binary](#rust-analyzer-language-server-binary) and have it automatically +work with any editor. We are not there yet, so some editor specific +setup is required. + +Additionally, rust-analyzer needs the sources of the standard library. +If the source code is not present, rust-analyzer will attempt to install +it automatically. + +To add the sources manually, run the following command: + + $ rustup component add rust-src + +## Toolchain + +Only the latest stable standard library source is officially supported +for use with rust-analyzer. If you are using an older toolchain or have +an override set, rust-analyzer may fail to understand the Rust source. +You will either need to update your toolchain or use an older version of +rust-analyzer that is compatible with your toolchain. + +If you are using an override in your project, you can still force +rust-analyzer to use the stable toolchain via the environment variable +`RUSTUP_TOOLCHAIN`. For example, with VS Code or coc-rust-analyzer: + + { "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "stable" } } + +## VS Code + +This is the best supported editor at the moment. The rust-analyzer +plugin for VS Code is maintained [in +tree](https://github.com/rust-lang/rust-analyzer/tree/master/editors/code). + +You can install the latest release of the plugin from [the +marketplace](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). + +Note that the plugin may cause conflicts with the [previous official +Rust +plugin](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust). +The latter is no longer maintained and should be uninstalled. + +The server binary is stored in the extension install directory, which +starts with `rust-lang.rust-analyzer-` and is located under: + +- Linux: `~/.vscode/extensions` + +- Linux (Remote, such as WSL): `~/.vscode-server/extensions` + +- macOS: `~/.vscode/extensions` + +- Windows: `%USERPROFILE%\.vscode\extensions` + +As an exception, on NixOS, the extension makes a copy of the server and +stores it under +`~/.config/Code/User/globalStorage/rust-lang.rust-analyzer`. + +Note that we only support the two most recent versions of VS Code. + +### Updates + +The extension will be updated automatically as new versions become +available. It will ask your permission to download the matching language +server version binary if needed. + +#### Nightly + +We ship nightly releases for VS Code. To help us out by testing the +newest code, you can enable pre-release versions in the Code extension +page. + +### Manual installation + +Alternatively, download a VSIX corresponding to your platform from the +[releases](https://github.com/rust-lang/rust-analyzer/releases) page. + +Install the extension with the `Extensions: Install from VSIX` command +within VS Code, or from the command line via: + + $ code --install-extension /path/to/rust-analyzer.vsix + +If you are running an unsupported platform, you can install +`rust-analyzer-no-server.vsix` and compile or obtain a server binary. +Copy the server anywhere, then add the path to your settings.json, for +example: + + { "rust-analyzer.server.path": "~/.local/bin/rust-analyzer-linux" } + +### Building From Source + +Both the server and the Code plugin can be installed from source: + + $ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer + $ cargo xtask install + +You’ll need Cargo, nodejs (matching a supported version of VS Code) and +npm for this. + +Note that installing via `xtask install` does not work for VS Code +Remote, instead you’ll need to install the `.vsix` manually. + +If you’re not using Code, you can compile and install only the LSP +server: + + $ cargo xtask install --server + +Make sure that `.cargo/bin` is in `$PATH` and precedes paths where +`rust-analyzer` may also be installed. Specifically, `rustup` includes a +proxy called `rust-analyzer`, which can cause problems if you’re +planning to use a source build or even a downloaded binary. + +## rust-analyzer Language Server Binary + +Other editors generally require the `rust-analyzer` binary to be in +`$PATH`. You can download pre-built binaries from the +[releases](https://github.com/rust-lang/rust-analyzer/releases) page. +You will need to uncompress and rename the binary for your platform, +e.g. from `rust-analyzer-aarch64-apple-darwin.gz` on Mac OS to +`rust-analyzer`, make it executable, then move it into a directory in +your `$PATH`. + +On Linux to install the `rust-analyzer` binary into `~/.local/bin`, +these commands should work: + + $ mkdir -p ~/.local/bin + $ curl -L https://github.com/rust-lang/rust-analyzer/releases/latest/download/rust-analyzer-x86_64-unknown-linux-gnu.gz | gunzip -c - > ~/.local/bin/rust-analyzer + $ chmod +x ~/.local/bin/rust-analyzer + +Make sure that `~/.local/bin` is listed in the `$PATH` variable and use +the appropriate URL if you’re not on a `x86-64` system. + +You don’t have to use `~/.local/bin`, any other path like `~/.cargo/bin` +or `/usr/local/bin` will work just as well. + +Alternatively, you can install it from source using the command below. +You’ll need the latest stable version of the Rust toolchain. + + $ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer + $ cargo xtask install --server + +If your editor can’t find the binary even though the binary is on your +`$PATH`, the likely explanation is that it doesn’t see the same `$PATH` +as the shell, see [this +issue](https://github.com/rust-lang/rust-analyzer/issues/1811). On Unix, +running the editor from a shell or changing the `.desktop` file to set +the environment should help. + +### rustup + +`rust-analyzer` is available in `rustup`: + + $ rustup component add rust-analyzer + +### Arch Linux + +The `rust-analyzer` binary can be installed from the repos or AUR (Arch +User Repository): + +- [`rust-analyzer`](https://www.archlinux.org/packages/community/x86_64/rust-analyzer/) + (built from latest tagged source) + +- [`rust-analyzer-git`](https://aur.archlinux.org/packages/rust-analyzer-git) + (latest Git version) + +Install it with pacman, for example: + + $ pacman -S rust-analyzer + +### Gentoo Linux + +`rust-analyzer` is available in the GURU repository: + +- [`dev-util/rust-analyzer`](https://gitweb.gentoo.org/repo/proj/guru.git/tree/dev-util/rust-analyzer?id=9895cea62602cfe599bd48e0fb02127411ca6e81) + builds from source + +- [`dev-util/rust-analyzer-bin`](https://gitweb.gentoo.org/repo/proj/guru.git/tree/dev-util/rust-analyzer-bin?id=9895cea62602cfe599bd48e0fb02127411ca6e81) + installs an official binary release + +If not already, GURU must be enabled (e.g. using +`app-eselect/eselect-repository`) and sync’d before running `emerge`: + + $ eselect repository enable guru && emaint sync -r guru + $ emerge rust-analyzer-bin + +### macOS + +The `rust-analyzer` binary can be installed via +[Homebrew](https://brew.sh/). + + $ brew install rust-analyzer + +## VS Code or VSCodium in Flatpak + +Setting up `rust-analyzer` with a Flatpak version of Code is not trivial +because of the Flatpak sandbox. While the sandbox can be disabled for +some directories, `/usr/bin` will always be mounted under +`/run/host/usr/bin`. This prevents access to the system’s C compiler, a +system-wide installation of Rust, or any other libraries you might want +to link to. Some compilers and libraries can be acquired as Flatpak +SDKs, such as `org.freedesktop.Sdk.Extension.rust-stable` or +`org.freedesktop.Sdk.Extension.llvm15`. + +If you use a Flatpak SDK for Rust, there should be no extra steps +necessary. + +If you want to use Flatpak in combination with `rustup`, the following +steps might help: + +- both Rust and `rustup` have to be installed using + . Distro packages *will not* work. + +- you need to launch Code, open a terminal and run `echo $PATH` + +- using + [Flatseal](https://flathub.org/apps/details/com.github.tchx84.Flatseal), + you must add an environment variable called `PATH`. Set its value to + the output from above, appending `:~/.cargo/bin`, where `~` is the + path to your home directory. You must replace `~`, as it won’t be + expanded otherwise. + +- while Flatseal is open, you must enable access to "All user files" + +A C compiler should already be available via `org.freedesktop.Sdk`. Any +other tools or libraries you will need to acquire from Flatpak. + +## Emacs + +Prerequisites: You have installed the [`rust-analyzer` +binary](#rust-analyzer-language-server-binary). + +To use `rust-analyzer`, you need to install and enable one of the two +popular LSP client implementations for Emacs, +[Eglot](https://github.com/joaotavora/eglot) or [LSP +Mode](https://github.com/emacs-lsp/lsp-mode). Both enable +`rust-analyzer` by default in rust buffers if it is available. + +### Eglot + +Eglot is the more minimalistic and lightweight LSP client for Emacs, +integrates well with existing Emacs functionality and is built into +Emacs starting from release 29. + +After installing Eglot, e.g. via `M-x package-install` (not needed from +Emacs 29), you can enable it via the `M-x eglot` command or load it +automatically in `rust-mode` via + + (add-hook 'rust-mode-hook 'eglot-ensure) + +To enable clippy, you will need to configure the initialization options +to pass the `check.command` setting. + + (add-to-list 'eglot-server-programs + '((rust-ts-mode rust-mode) . + ("rust-analyzer" :initializationOptions (:check (:command "clippy"))))) + +For more detailed instructions and options see the [Eglot +manual](https://joaotavora.github.io/eglot) (also available from Emacs +via `M-x info`) and the [Eglot +readme](https://github.com/joaotavora/eglot/blob/master/README.md). + +Eglot does not support the rust-analyzer extensions to the +language-server protocol and does not aim to do so in the future. The +[eglot-x](https://github.com/nemethf/eglot-x#rust-analyzer-extensions) +package adds experimental support for those LSP extensions. + +### LSP Mode + +LSP-mode is the original LSP-client for emacs. Compared to Eglot it has +a larger codebase and supports more features, like LSP protocol +extensions. With extension packages like [LSP +UI](https://github.com/emacs-lsp/lsp-mode) it offers a lot of visual +eyecandy. Further it integrates well with [DAP +mode](https://github.com/emacs-lsp/dap-mode) for support of the Debug +Adapter Protocol. + +You can install LSP-mode via `M-x package-install` and then run it via +the `M-x lsp` command or load it automatically in rust buffers with + + (add-hook 'rust-mode-hook 'lsp-deferred) + +For more information on how to set up LSP mode and its extension package +see the instructions in the [LSP mode +manual](https://emacs-lsp.github.io/lsp-mode/page/installation). Also +see the [rust-analyzer +section](https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/) +for `rust-analyzer` specific options and commands, which you can +optionally bind to keys. + +Note the excellent +[guide](https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/) from +[@rksm](https://github.com/rksm) on how to set-up Emacs for Rust +development with LSP mode and several other packages. + +## Vim/Neovim + +Prerequisites: You have installed the [`rust-analyzer` +binary](#rust-analyzer-language-server-binary). Not needed if the +extension can install/update it on its own, coc-rust-analyzer is one +example. + +There are several LSP client implementations for Vim or Neovim: + +### coc-rust-analyzer + +1. Install coc.nvim by following the instructions at + [coc.nvim](https://github.com/neoclide/coc.nvim) (Node.js required) + +2. Run `:CocInstall coc-rust-analyzer` to install + [coc-rust-analyzer](https://github.com/fannheyward/coc-rust-analyzer), + this extension implements *most* of the features supported in the + VSCode extension: + + - automatically install and upgrade stable/nightly releases + + - same configurations as VSCode extension, + `rust-analyzer.server.path`, `rust-analyzer.cargo.features` etc. + + - same commands too, `rust-analyzer.analyzerStatus`, + `rust-analyzer.ssr` etc. + + - inlay hints for variables and method chaining, *Neovim Only* + +Note: for code actions, use `coc-codeaction-cursor` and +`coc-codeaction-selected`; `coc-codeaction` and `coc-codeaction-line` +are unlikely to be useful. + +### LanguageClient-neovim + +1. Install LanguageClient-neovim by following the instructions + [here](https://github.com/autozimu/LanguageClient-neovim) + + - The GitHub project wiki has extra tips on configuration + +2. Configure by adding this to your Vim/Neovim config file (replacing + the existing Rust-specific line if it exists): + + let g:LanguageClient_serverCommands = { + \ 'rust': ['rust-analyzer'], + \ } + +### YouCompleteMe + +Install YouCompleteMe by following the instructions +[here](https://github.com/ycm-core/YouCompleteMe#installation). + +rust-analyzer is the default in ycm, it should work out of the box. + +### ALE + +To use the LSP server in [ale](https://github.com/dense-analysis/ale): + + let g:ale_linters = {'rust': ['analyzer']} + +### nvim-lsp + +Neovim 0.5 has built-in language server support. For a quick start +configuration of rust-analyzer, use +[neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig#rust_analyzer). +Once `neovim/nvim-lspconfig` is installed, use +`lua require'lspconfig'.rust_analyzer.setup({})` in your `init.vim`. + +You can also pass LSP settings to the server: + + lua << EOF + local nvim_lsp = require'lspconfig' + + local on_attach = function(client) + require'completion'.on_attach(client) + end + + nvim_lsp.rust_analyzer.setup({ + on_attach=on_attach, + settings = { + ["rust-analyzer"] = { + imports = { + granularity = { + group = "module", + }, + prefix = "self", + }, + cargo = { + buildScripts = { + enable = true, + }, + }, + procMacro = { + enable = true + }, + } + } + }) + EOF + +See for more tips on +getting started. + +Check out for a batteries +included rust-analyzer setup for Neovim. + +### vim-lsp + +vim-lsp is installed by following [the plugin +instructions](https://github.com/prabirshrestha/vim-lsp). It can be as +simple as adding this line to your `.vimrc`: + + Plug 'prabirshrestha/vim-lsp' + +Next you need to register the `rust-analyzer` binary. If it is available +in `$PATH`, you may want to add this to your `.vimrc`: + + if executable('rust-analyzer') + au User lsp_setup call lsp#register_server({ + \ 'name': 'Rust Language Server', + \ 'cmd': {server_info->['rust-analyzer']}, + \ 'whitelist': ['rust'], + \ }) + endif + +There is no dedicated UI for the server configuration, so you would need +to send any options as a value of the `initialization_options` field, as +described in the [Configuration](#configuration) section. Here is an +example of how to enable the proc-macro support: + + if executable('rust-analyzer') + au User lsp_setup call lsp#register_server({ + \ 'name': 'Rust Language Server', + \ 'cmd': {server_info->['rust-analyzer']}, + \ 'whitelist': ['rust'], + \ 'initialization_options': { + \ 'cargo': { + \ 'buildScripts': { + \ 'enable': v:true, + \ }, + \ }, + \ 'procMacro': { + \ 'enable': v:true, + \ }, + \ }, + \ }) + endif + +## Sublime Text + +### Sublime Text 4: + +- Follow the instructions in + [LSP-rust-analyzer](https://github.com/sublimelsp/LSP-rust-analyzer). + +Install +[LSP-file-watcher-chokidar](https://packagecontrol.io/packages/LSP-file-watcher-chokidar) +to enable file watching (`workspace/didChangeWatchedFiles`). + +### Sublime Text 3: + +- Install the [`rust-analyzer` + binary](#rust-analyzer-language-server-binary). + +- Install the [LSP package](https://packagecontrol.io/packages/LSP). + +- From the command palette, run `LSP: Enable Language Server Globally` + and select `rust-analyzer`. + +If it worked, you should see "rust-analyzer, Line X, Column Y" on the +left side of the status bar, and after waiting a bit, functionalities +like tooltips on hovering over variables should become available. + +If you get an error saying `No such file or directory: 'rust-analyzer'`, +see the [`rust-analyzer` binary](#rust-analyzer-language-server-binary) +section on installing the language server binary. + +## GNOME Builder + +GNOME Builder 3.37.1 and newer has native `rust-analyzer` support. If +the LSP binary is not available, GNOME Builder can install it when +opening a Rust file. + +## Eclipse IDE + +Support for Rust development in the Eclipse IDE is provided by [Eclipse +Corrosion](https://github.com/eclipse/corrosion). If available in PATH +or in some standard location, `rust-analyzer` is detected and powers +editing of Rust files without further configuration. If `rust-analyzer` +is not detected, Corrosion will prompt you for configuration of your +Rust toolchain and language server with a link to the *Window > +Preferences > Rust* preference page; from here a button allows to +download and configure `rust-analyzer`, but you can also reference +another installation. You’ll need to close and reopen all .rs and Cargo +files, or to restart the IDE, for this change to take effect. + +## Kate Text Editor + +Support for the language server protocol is built into Kate through the +LSP plugin, which is included by default. It is preconfigured to use +rust-analyzer for Rust sources since Kate 21.12. + +To change rust-analyzer config options, start from the following example +and put it into Kate’s "User Server Settings" tab (located under the LSP +Client settings): + + { + "servers": { + "rust": { + "initializationOptions": { + "cachePriming": { + "enable": false + }, + "check": { + "allTargets": false + }, + "checkOnSave": false + } + } + } + } + +Then click on apply, and restart the LSP server for your rust project. + +## juCi++ + +[juCi++](https://gitlab.com/cppit/jucipp) has built-in support for the +language server protocol, and since version 1.7.0 offers installation of +both Rust and rust-analyzer when opening a Rust file. + +## Kakoune + +[Kakoune](https://kakoune.org/) supports LSP with the help of +[`kak-lsp`](https://github.com/kak-lsp/kak-lsp). Follow the +[instructions](https://github.com/kak-lsp/kak-lsp#installation) to +install `kak-lsp`. To configure `kak-lsp`, refer to the [configuration +section](https://github.com/kak-lsp/kak-lsp#configuring-kak-lsp) which +is basically about copying the [configuration +file](https://github.com/kak-lsp/kak-lsp/blob/master/kak-lsp.toml) in +the right place (latest versions should use `rust-analyzer` by default). + +Finally, you need to configure Kakoune to talk to `kak-lsp` (see [Usage +section](https://github.com/kak-lsp/kak-lsp#usage)). A basic +configuration will only get you LSP but you can also activate inlay +diagnostics and auto-formatting on save. The following might help you +get all of this. + + eval %sh{kak-lsp --kakoune -s $kak_session} # Not needed if you load it with plug.kak. + hook global WinSetOption filetype=rust %{ + # Enable LSP + lsp-enable-window + + # Auto-formatting on save + hook window BufWritePre .* lsp-formatting-sync + + # Configure inlay hints (only on save) + hook window -group rust-inlay-hints BufWritePost .* rust-analyzer-inlay-hints + hook -once -always window WinSetOption filetype=.* %{ + remove-hooks window rust-inlay-hints + } + } + +## Helix + +[Helix](https://docs.helix-editor.com/) supports LSP by default. +However, it won’t install `rust-analyzer` automatically. You can follow +instructions for installing [`rust-analyzer` +binary](#rust-analyzer-language-server-binary). + +## Visual Studio 2022 + +There are multiple rust-analyzer extensions for Visual Studio 2022 on +Windows: + +### rust-analyzer.vs + +(License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 +International) + +[Visual Studio +Marketplace](https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer) + +[GitHub](https://github.com/kitamstudios/rust-analyzer/) + +Support for Rust development in the Visual Studio IDE is enabled by the +[rust-analyzer](https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer) +package. Either click on the download link or install from IDE’s +extension manager. For now [Visual Studio +2022](https://visualstudio.microsoft.com/downloads/) is required. All +editions are supported viz. Community, Professional & Enterprise. The +package aims to provide 0-friction installation and therefore comes +loaded with most things required including rust-analyzer binary. If +anything it needs is missing, appropriate errors / warnings will guide +the user. E.g. cargo.exe needs to be in path and the package will tell +you as much. This package is under rapid active development. So if you +encounter any issues please file it at +[rust-analyzer.vs](https://github.com/kitamstudios/rust-analyzer/). + +### VS\_RustAnalyzer + +(License: GPL) + +[Visual Studio +Marketplace](https://marketplace.visualstudio.com/items?itemName=cchharris.vsrustanalyzer) + +[GitHub](https://github.com/cchharris/VS-RustAnalyzer) + +### SourceGear Rust + +(License: closed source) + +[Visual Studio +Marketplace](https://marketplace.visualstudio.com/items?itemName=SourceGear.SourceGearRust) + +[GitHub (docs, issues, +discussions)](https://github.com/sourcegear/rust-vs-extension) + +- Free (no-cost) + +- Supports all editions of Visual Studio 2022 on Windows: Community, + Professional, or Enterprise + +## Lapce + +[Lapce](https://lapce.dev/) has a Rust plugin which you can install +directly. Unfortunately, it downloads an old version of `rust-analyzer`, +but you can set the server path under Settings. + +## Crates + +There is a package named `ra_ap_rust_analyzer` available on +[crates.io](https://crates.io/crates/ra_ap_rust-analyzer), for someone +who wants to use it programmatically. + +For more details, see [the publish +workflow](https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml). + +## Zed + +[Zed](https://zed.dev) has native `rust-analyzer` support. If the LSP +binary is not available, Zed can install it when opening a Rust file. \ No newline at end of file diff --git a/docs/book/src/non_cargo_based_projects/README.md b/docs/book/src/non_cargo_based_projects/README.md new file mode 100644 index 000000000000..b80347fce507 --- /dev/null +++ b/docs/book/src/non_cargo_based_projects/README.md @@ -0,0 +1,159 @@ +# 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: + + interface JsonProject { + /// Path to the sysroot directory. + /// + /// The sysroot is where rustc looks for the + /// crates that are built-in to rust, such as + /// std. + /// + /// https://doc.rust-lang.org/rustc/command-line-arguments.html#--sysroot-override-the-system-root + /// + /// To see the current value of sysroot, you + /// can query rustc: + /// + /// ``` + /// $ rustc --print sysroot + /// /Users/yourname/.rustup/toolchains/stable-x86_64-apple-darwin + /// ``` + sysroot?: string; + /// Path to the directory with *source code* of + /// sysroot crates. + /// + /// By default, this is `lib/rustlib/src/rust/library` + /// relative to the sysroot. + /// + /// It should point to the directory where std, + /// core, and friends can be found: + /// + /// https://github.com/rust-lang/rust/tree/master/library. + /// + /// If provided, rust-analyzer automatically adds + /// dependencies on sysroot crates. Conversely, + /// if you omit this path, you can specify sysroot + /// dependencies yourself and, for example, have + /// several different "sysroots" in one graph of + /// crates. + sysroot_src?: 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 { + /// Optional crate name used for display purposes, + /// without affecting semantics. See the `deps` + /// key for semantically-significant crate names. + display_name?: string; + /// Path to the root module of the crate. + root_module: string; + /// Edition of the crate. + edition: "2015" | "2018" | "2021"; + /// Dependencies + deps: Dep[]; + /// Should this crate be treated as a member of + /// current "workspace". + /// + /// By default, inferred from the `root_module` + /// (members are the crates which reside inside + /// the directory opened in the editor). + /// + /// Set this to `false` for things like standard + /// library and 3rd party crates to enable + /// performance optimizations (rust-analyzer + /// assumes that non-member crates don't change). + is_workspace_member?: boolean; + /// Optionally specify the (super)set of `.rs` + /// files comprising this crate. + /// + /// By default, rust-analyzer assumes that only + /// files under `root_module.parent` can belong + /// to a crate. `include_dirs` are included + /// recursively, unless a subdirectory is in + /// `exclude_dirs`. + /// + /// Different crates can share the same `source`. + /// + /// If two crates share an `.rs` file in common, + /// they *must* have the same `source`. + /// rust-analyzer assumes that files from one + /// source can't refer to files in another source. + source?: { + include_dirs: string[], + exclude_dirs: string[], + }, + /// The set of cfgs activated for a given crate, like + /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`. + cfg: string[]; + /// Target triple for this Crate. + /// + /// Used when running `rustc --print cfg` + /// to get target-specific cfgs. + target?: string; + /// Environment variables, used for + /// the `env!` macro + env: { [key: string]: string; }, + + /// Whether the crate is a proc-macro crate. + is_proc_macro: boolean; + /// For proc-macro crates, path to compiled + /// 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 three ways to feed `rust-project.json` to rust-analyzer: + +- Place `rust-project.json` file at the root of the project, and + rust-analyzer 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. + +Relative paths are interpreted relative to `rust-project.json` file +location or (for inline JSON) relative to `rootUri`. + +See for a +small example. + +You can set the `RA_LOG` environment variable to `rust_analyzer=info` to +inspect how rust-analyzer handles config and project loading. + +Note that calls to `cargo check` are disabled when using +`rust-project.json` by default, so compilation errors and warnings will +no longer be sent to your LSP client. To enable these compilation errors +you will need to specify explicitly what command rust-analyzer should +run to perform the checks using the +`rust-analyzer.check.overrideCommand` configuration. As an example, the +following configuration explicitly sets `cargo check` as the `check` +command. + + { "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] } + +`check.overrideCommand` requires the command specified to output json +error messages for rust-analyzer to consume. The `--message-format=json` +flag does this for `cargo check` so whichever command you use must also +output errors in this format. See the [Configuration](#_configuration) +section for more information. \ No newline at end of file diff --git a/docs/book/src/privacy/README.md b/docs/book/src/privacy/README.md new file mode 100644 index 000000000000..602c68d6f67d --- /dev/null +++ b/docs/book/src/privacy/README.md @@ -0,0 +1,15 @@ +# Privacy + +The LSP server performs no network access in itself, but runs +`cargo metadata` which will update or download the crate registry and +the source code of the project dependencies. If enabled (the default), +build scripts and procedural macros can do anything. + +The Code extension does not access the network. + +Any other editor plugins are not under the control of the +`rust-analyzer` developers. For any privacy concerns, you should check +with their respective developers. + +For `rust-analyzer` developers, `cargo xtask release` uses the GitHub +API to put together the release notes. diff --git a/docs/book/src/security/README.md b/docs/book/src/security/README.md new file mode 100644 index 000000000000..1444af03248d --- /dev/null +++ b/docs/book/src/security/README.md @@ -0,0 +1,19 @@ +# Security + +At the moment, rust-analyzer assumes that all code is trusted. Here is a +**non-exhaustive** list of ways to make rust-analyzer execute arbitrary +code: + +- proc macros and build scripts are executed by default + +- `.cargo/config` can override `rustc` with an arbitrary executable + +- `rust-toolchain.toml` can override `rustc` with an arbitrary + executable + +- VS Code plugin reads configuration from project directory, and that + can be used to override paths to various executables, like `rustfmt` + or `rust-analyzer` itself. + +- rust-analyzer’s syntax trees library uses a lot of `unsafe` and + hasn’t been properly audited for memory safety. \ No newline at end of file diff --git a/docs/book/src/troubleshooting/README.md b/docs/book/src/troubleshooting/README.md new file mode 100644 index 000000000000..02d0affe6f0b --- /dev/null +++ b/docs/book/src/troubleshooting/README.md @@ -0,0 +1,48 @@ +# Troubleshooting + +Start with looking at the rust-analyzer version. Try **rust-analyzer: +Show RA Version** in VS Code (using **Command Palette** feature +typically activated by Ctrl+Shift+P) or `rust-analyzer --version` in the +command line. If the date is more than a week ago, it’s better to update +rust-analyzer version. + +The next thing to check would be panic messages in rust-analyzer’s log. +Log messages are printed to stderr, in VS Code you can see them in the +`Output > Rust Analyzer Language Server` tab of the panel. To see more +logs, set the `RA_LOG=info` environment variable, this can be done +either by setting the environment variable manually or by using +`rust-analyzer.server.extraEnv`, note that both of these approaches +require the server to be restarted. + +To fully capture LSP messages between the editor and the server, set +`"rust-analyzer.trace.server": "verbose"` config and check +`Output > Rust Analyzer Language Server Trace`. + +The root cause for many “nothing works” problems is that rust-analyzer +fails to understand the project structure. To debug that, first note the +`rust-analyzer` section in the status bar. If it has an error icon and +red, that’s the problem (hover will have somewhat helpful error +message). **rust-analyzer: Status** prints dependency information for +the current file. Finally, `RA_LOG=project_model=debug` enables verbose +logs during project loading. + +If rust-analyzer outright crashes, try running +`rust-analyzer analysis-stats /path/to/project/directory/` on the +command line. This command type checks the whole project in batch mode +bypassing LSP machinery. + +When filing issues, it is useful (but not necessary) to try to minimize +examples. An ideal bug reproduction looks like this: + + $ git clone https://github.com/username/repo.git && cd repo && git switch --detach commit-hash + $ rust-analyzer --version + rust-analyzer dd12184e4 2021-05-08 dev + $ rust-analyzer analysis-stats . + 💀 💀 💀 + +It is especially useful when the `repo` doesn’t use external crates or +the standard library. + +If you want to go as far as to modify the source code to debug the +problem, be sure to take a look at the [dev +docs](https://github.com/rust-lang/rust-analyzer/tree/master/docs/dev)! \ No newline at end of file diff --git a/docs/user/.gitignore b/docs/user/.gitignore deleted file mode 100644 index c32b1bcec2ee..000000000000 --- a/docs/user/.gitignore +++ /dev/null @@ -1 +0,0 @@ -manual.html diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc deleted file mode 100644 index 7091ea1ce9a7..000000000000 --- a/docs/user/generated_config.adoc +++ /dev/null @@ -1,899 +0,0 @@ -[[rust-analyzer.assist.emitMustUse]]rust-analyzer.assist.emitMustUse (default: `false`):: -+ --- -Whether to insert #[must_use] when generating `as_` methods -for enum variants. --- -[[rust-analyzer.assist.expressionFillDefault]]rust-analyzer.assist.expressionFillDefault (default: `"todo"`):: -+ --- -Placeholder expression to use for missing expressions in assists. --- -[[rust-analyzer.cachePriming.enable]]rust-analyzer.cachePriming.enable (default: `true`):: -+ --- -Warm up caches on project load. --- -[[rust-analyzer.cachePriming.numThreads]]rust-analyzer.cachePriming.numThreads (default: `0`):: -+ --- -How many worker threads to handle priming caches. The default `0` means to pick automatically. --- -[[rust-analyzer.cargo.autoreload]]rust-analyzer.cargo.autoreload (default: `true`):: -+ --- -Automatically refresh project info via `cargo metadata` on -`Cargo.toml` or `.cargo/config.toml` changes. --- -[[rust-analyzer.cargo.buildScripts.enable]]rust-analyzer.cargo.buildScripts.enable (default: `true`):: -+ --- -Run build scripts (`build.rs`) for more precise code analysis. --- -[[rust-analyzer.cargo.buildScripts.invocationLocation]]rust-analyzer.cargo.buildScripts.invocationLocation (default: `"workspace"`):: -+ --- -Specifies the working directory for running build scripts. -- "workspace": run build scripts for a workspace in the workspace's root directory. - This is incompatible with `#rust-analyzer.cargo.buildScripts.invocationStrategy#` set to `once`. -- "root": run build scripts in the project's root directory. -This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` -is set. --- -[[rust-analyzer.cargo.buildScripts.invocationStrategy]]rust-analyzer.cargo.buildScripts.invocationStrategy (default: `"per_workspace"`):: -+ --- -Specifies the invocation strategy to use when running the build scripts command. -If `per_workspace` is set, the command will be executed for each workspace. -If `once` is set, the command will be executed once. -This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` -is set. --- -[[rust-analyzer.cargo.buildScripts.overrideCommand]]rust-analyzer.cargo.buildScripts.overrideCommand (default: `null`):: -+ --- -Override the command rust-analyzer uses to run build scripts and -build procedural macros. The command is required to output json -and should therefore include `--message-format=json` or a similar -option. - -If there are multiple linked projects/workspaces, this command is invoked for -each of them, with the working directory being the workspace root -(i.e., the folder containing the `Cargo.toml`). This can be overwritten -by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#` and -`#rust-analyzer.cargo.buildScripts.invocationLocation#`. - -By default, a cargo invocation will be constructed for the configured -targets and features, with the following base command line: - -```bash -cargo check --quiet --workspace --message-format=json --all-targets -``` -. --- -[[rust-analyzer.cargo.buildScripts.useRustcWrapper]]rust-analyzer.cargo.buildScripts.useRustcWrapper (default: `true`):: -+ --- -Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to -avoid checking unnecessary things. --- -[[rust-analyzer.cargo.cfgs]]rust-analyzer.cargo.cfgs (default: `{}`):: -+ --- -List of cfg options to enable with the given values. --- -[[rust-analyzer.cargo.extraArgs]]rust-analyzer.cargo.extraArgs (default: `[]`):: -+ --- -Extra arguments that are passed to every cargo invocation. --- -[[rust-analyzer.cargo.extraEnv]]rust-analyzer.cargo.extraEnv (default: `{}`):: -+ --- -Extra environment variables that will be set when running cargo, rustc -or other commands within the workspace. Useful for setting RUSTFLAGS. --- -[[rust-analyzer.cargo.features]]rust-analyzer.cargo.features (default: `[]`):: -+ --- -List of features to activate. - -Set this to `"all"` to pass `--all-features` to cargo. --- -[[rust-analyzer.cargo.noDefaultFeatures]]rust-analyzer.cargo.noDefaultFeatures (default: `false`):: -+ --- -Whether to pass `--no-default-features` to cargo. --- -[[rust-analyzer.cargo.sysroot]]rust-analyzer.cargo.sysroot (default: `"discover"`):: -+ --- -Relative path to the sysroot, or "discover" to try to automatically find it via -"rustc --print sysroot". - -Unsetting this disables sysroot loading. - -This option does not take effect until rust-analyzer is restarted. --- -[[rust-analyzer.cargo.sysrootSrc]]rust-analyzer.cargo.sysrootSrc (default: `null`):: -+ --- -Relative path to the sysroot library sources. If left unset, this will default to -`{cargo.sysroot}/lib/rustlib/src/rust/library`. - -This option does not take effect until rust-analyzer is restarted. --- -[[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`):: -+ --- -Compilation target override (target triple). --- -[[rust-analyzer.cargo.unsetTest]]rust-analyzer.cargo.unsetTest (default: `["core"]`):: -+ --- -Unsets the implicit `#[cfg(test)]` for the specified crates. --- -[[rust-analyzer.checkOnSave]]rust-analyzer.checkOnSave (default: `true`):: -+ --- -Run the check command for diagnostics on save. --- -[[rust-analyzer.check.allTargets]]rust-analyzer.check.allTargets (default: `true`):: -+ --- -Check all targets and tests (`--all-targets`). --- -[[rust-analyzer.check.command]]rust-analyzer.check.command (default: `"check"`):: -+ --- -Cargo command to use for `cargo check`. --- -[[rust-analyzer.check.extraArgs]]rust-analyzer.check.extraArgs (default: `[]`):: -+ --- -Extra arguments for `cargo check`. --- -[[rust-analyzer.check.extraEnv]]rust-analyzer.check.extraEnv (default: `{}`):: -+ --- -Extra environment variables that will be set when running `cargo check`. -Extends `#rust-analyzer.cargo.extraEnv#`. --- -[[rust-analyzer.check.features]]rust-analyzer.check.features (default: `null`):: -+ --- -List of features to activate. Defaults to -`#rust-analyzer.cargo.features#`. - -Set to `"all"` to pass `--all-features` to Cargo. --- -[[rust-analyzer.check.ignore]]rust-analyzer.check.ignore (default: `[]`):: -+ --- -List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore. - -For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,... --- -[[rust-analyzer.check.invocationLocation]]rust-analyzer.check.invocationLocation (default: `"workspace"`):: -+ --- -Specifies the working directory for running checks. -- "workspace": run checks for workspaces in the corresponding workspaces' root directories. - This falls back to "root" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`. -- "root": run checks in the project's root directory. -This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#` -is set. --- -[[rust-analyzer.check.invocationStrategy]]rust-analyzer.check.invocationStrategy (default: `"per_workspace"`):: -+ --- -Specifies the invocation strategy to use when running the check command. -If `per_workspace` is set, the command will be executed for each workspace. -If `once` is set, the command will be executed once. -This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#` -is set. --- -[[rust-analyzer.check.noDefaultFeatures]]rust-analyzer.check.noDefaultFeatures (default: `null`):: -+ --- -Whether to pass `--no-default-features` to Cargo. Defaults to -`#rust-analyzer.cargo.noDefaultFeatures#`. --- -[[rust-analyzer.check.overrideCommand]]rust-analyzer.check.overrideCommand (default: `null`):: -+ --- -Override the command rust-analyzer uses instead of `cargo check` for -diagnostics on save. The command is required to output json and -should therefore include `--message-format=json` or a similar option -(if your client supports the `colorDiagnosticOutput` experimental -capability, you can use `--message-format=json-diagnostic-rendered-ansi`). - -If you're changing this because you're using some tool wrapping -Cargo, you might also want to change -`#rust-analyzer.cargo.buildScripts.overrideCommand#`. - -If there are multiple linked projects/workspaces, this command is invoked for -each of them, with the working directory being the workspace root -(i.e., the folder containing the `Cargo.toml`). This can be overwritten -by changing `#rust-analyzer.cargo.check.invocationStrategy#` and -`#rust-analyzer.cargo.check.invocationLocation#`. - -An example command would be: - -```bash -cargo check --workspace --message-format=json --all-targets -``` -. --- -[[rust-analyzer.check.targets]]rust-analyzer.check.targets (default: `null`):: -+ --- -Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty. - -Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g. -`["aarch64-apple-darwin", "x86_64-apple-darwin"]`. - -Aliased as `"checkOnSave.targets"`. --- -[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`):: -+ --- -Toggles the additional completions that automatically add imports when completed. -Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled. --- -[[rust-analyzer.completion.autoself.enable]]rust-analyzer.completion.autoself.enable (default: `true`):: -+ --- -Toggles the additional completions that automatically show method calls and field accesses -with `self` prefixed to them when inside a method. --- -[[rust-analyzer.completion.callable.snippets]]rust-analyzer.completion.callable.snippets (default: `"fill_arguments"`):: -+ --- -Whether to add parenthesis and argument snippets when completing function. --- -[[rust-analyzer.completion.fullFunctionSignatures.enable]]rust-analyzer.completion.fullFunctionSignatures.enable (default: `false`):: -+ --- -Whether to show full function/method signatures in completion docs. --- -[[rust-analyzer.completion.limit]]rust-analyzer.completion.limit (default: `null`):: -+ --- -Maximum number of completions to return. If `None`, the limit is infinite. --- -[[rust-analyzer.completion.postfix.enable]]rust-analyzer.completion.postfix.enable (default: `true`):: -+ --- -Whether to show postfix snippets like `dbg`, `if`, `not`, etc. --- -[[rust-analyzer.completion.privateEditable.enable]]rust-analyzer.completion.privateEditable.enable (default: `false`):: -+ --- -Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position. --- -[[rust-analyzer.completion.snippets.custom]]rust-analyzer.completion.snippets.custom:: -+ --- -Default: ----- -{ - "Arc::new": { - "postfix": "arc", - "body": "Arc::new(${receiver})", - "requires": "std::sync::Arc", - "description": "Put the expression into an `Arc`", - "scope": "expr" - }, - "Rc::new": { - "postfix": "rc", - "body": "Rc::new(${receiver})", - "requires": "std::rc::Rc", - "description": "Put the expression into an `Rc`", - "scope": "expr" - }, - "Box::pin": { - "postfix": "pinbox", - "body": "Box::pin(${receiver})", - "requires": "std::boxed::Box", - "description": "Put the expression into a pinned `Box`", - "scope": "expr" - }, - "Ok": { - "postfix": "ok", - "body": "Ok(${receiver})", - "description": "Wrap the expression in a `Result::Ok`", - "scope": "expr" - }, - "Err": { - "postfix": "err", - "body": "Err(${receiver})", - "description": "Wrap the expression in a `Result::Err`", - "scope": "expr" - }, - "Some": { - "postfix": "some", - "body": "Some(${receiver})", - "description": "Wrap the expression in an `Option::Some`", - "scope": "expr" - } - } ----- -Custom completion snippets. - --- -[[rust-analyzer.diagnostics.disabled]]rust-analyzer.diagnostics.disabled (default: `[]`):: -+ --- -List of rust-analyzer diagnostics to disable. --- -[[rust-analyzer.diagnostics.enable]]rust-analyzer.diagnostics.enable (default: `true`):: -+ --- -Whether to show native rust-analyzer diagnostics. --- -[[rust-analyzer.diagnostics.experimental.enable]]rust-analyzer.diagnostics.experimental.enable (default: `false`):: -+ --- -Whether to show experimental rust-analyzer diagnostics that might -have more false positives than usual. --- -[[rust-analyzer.diagnostics.remapPrefix]]rust-analyzer.diagnostics.remapPrefix (default: `{}`):: -+ --- -Map of prefixes to be substituted when parsing diagnostic file paths. -This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`. --- -[[rust-analyzer.diagnostics.warningsAsHint]]rust-analyzer.diagnostics.warningsAsHint (default: `[]`):: -+ --- -List of warnings that should be displayed with hint severity. - -The warnings will be indicated by faded text or three dots in code -and will not show up in the `Problems Panel`. --- -[[rust-analyzer.diagnostics.warningsAsInfo]]rust-analyzer.diagnostics.warningsAsInfo (default: `[]`):: -+ --- -List of warnings that should be displayed with info severity. - -The warnings will be indicated by a blue squiggly underline in code -and a blue icon in the `Problems Panel`. --- -[[rust-analyzer.files.excludeDirs]]rust-analyzer.files.excludeDirs (default: `[]`):: -+ --- -These directories will be ignored by rust-analyzer. They are -relative to the workspace root, and globs are not supported. You may -also need to add the folders to Code's `files.watcherExclude`. --- -[[rust-analyzer.files.watcher]]rust-analyzer.files.watcher (default: `"client"`):: -+ --- -Controls file watching implementation. --- -[[rust-analyzer.highlightRelated.breakPoints.enable]]rust-analyzer.highlightRelated.breakPoints.enable (default: `true`):: -+ --- -Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords. --- -[[rust-analyzer.highlightRelated.closureCaptures.enable]]rust-analyzer.highlightRelated.closureCaptures.enable (default: `true`):: -+ --- -Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure. --- -[[rust-analyzer.highlightRelated.exitPoints.enable]]rust-analyzer.highlightRelated.exitPoints.enable (default: `true`):: -+ --- -Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`). --- -[[rust-analyzer.highlightRelated.references.enable]]rust-analyzer.highlightRelated.references.enable (default: `true`):: -+ --- -Enables highlighting of related references while the cursor is on any identifier. --- -[[rust-analyzer.highlightRelated.yieldPoints.enable]]rust-analyzer.highlightRelated.yieldPoints.enable (default: `true`):: -+ --- -Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords. --- -[[rust-analyzer.hover.actions.debug.enable]]rust-analyzer.hover.actions.debug.enable (default: `true`):: -+ --- -Whether to show `Debug` action. Only applies when -`#rust-analyzer.hover.actions.enable#` is set. --- -[[rust-analyzer.hover.actions.enable]]rust-analyzer.hover.actions.enable (default: `true`):: -+ --- -Whether to show HoverActions in Rust files. --- -[[rust-analyzer.hover.actions.gotoTypeDef.enable]]rust-analyzer.hover.actions.gotoTypeDef.enable (default: `true`):: -+ --- -Whether to show `Go to Type Definition` action. Only applies when -`#rust-analyzer.hover.actions.enable#` is set. --- -[[rust-analyzer.hover.actions.implementations.enable]]rust-analyzer.hover.actions.implementations.enable (default: `true`):: -+ --- -Whether to show `Implementations` action. Only applies when -`#rust-analyzer.hover.actions.enable#` is set. --- -[[rust-analyzer.hover.actions.references.enable]]rust-analyzer.hover.actions.references.enable (default: `false`):: -+ --- -Whether to show `References` action. Only applies when -`#rust-analyzer.hover.actions.enable#` is set. --- -[[rust-analyzer.hover.actions.run.enable]]rust-analyzer.hover.actions.run.enable (default: `true`):: -+ --- -Whether to show `Run` action. Only applies when -`#rust-analyzer.hover.actions.enable#` is set. --- -[[rust-analyzer.hover.documentation.enable]]rust-analyzer.hover.documentation.enable (default: `true`):: -+ --- -Whether to show documentation on hover. --- -[[rust-analyzer.hover.documentation.keywords.enable]]rust-analyzer.hover.documentation.keywords.enable (default: `true`):: -+ --- -Whether to show keyword hover popups. Only applies when -`#rust-analyzer.hover.documentation.enable#` is set. --- -[[rust-analyzer.hover.links.enable]]rust-analyzer.hover.links.enable (default: `true`):: -+ --- -Use markdown syntax for links on hover. --- -[[rust-analyzer.hover.memoryLayout.alignment]]rust-analyzer.hover.memoryLayout.alignment (default: `"hexadecimal"`):: -+ --- -How to render the align information in a memory layout hover. --- -[[rust-analyzer.hover.memoryLayout.enable]]rust-analyzer.hover.memoryLayout.enable (default: `true`):: -+ --- -Whether to show memory layout data on hover. --- -[[rust-analyzer.hover.memoryLayout.niches]]rust-analyzer.hover.memoryLayout.niches (default: `false`):: -+ --- -How to render the niche information in a memory layout hover. --- -[[rust-analyzer.hover.memoryLayout.offset]]rust-analyzer.hover.memoryLayout.offset (default: `"hexadecimal"`):: -+ --- -How to render the offset information in a memory layout hover. --- -[[rust-analyzer.hover.memoryLayout.size]]rust-analyzer.hover.memoryLayout.size (default: `"both"`):: -+ --- -How to render the size information in a memory layout hover. --- -[[rust-analyzer.imports.granularity.enforce]]rust-analyzer.imports.granularity.enforce (default: `false`):: -+ --- -Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file. --- -[[rust-analyzer.imports.granularity.group]]rust-analyzer.imports.granularity.group (default: `"crate"`):: -+ --- -How imports should be grouped into use statements. --- -[[rust-analyzer.imports.group.enable]]rust-analyzer.imports.group.enable (default: `true`):: -+ --- -Group inserted imports by the https://rust-analyzer.github.io/manual.html#auto-import[following order]. Groups are separated by newlines. --- -[[rust-analyzer.imports.merge.glob]]rust-analyzer.imports.merge.glob (default: `true`):: -+ --- -Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`. --- -[[rust-analyzer.imports.preferNoStd]]rust-analyzer.imports.preferNoStd (default: `false`):: -+ --- -Prefer to unconditionally use imports of the core and alloc crate, over the std crate. --- -[[rust-analyzer.imports.preferPrelude]]rust-analyzer.imports.preferPrelude (default: `false`):: -+ --- -Whether to prefer import paths containing a `prelude` module. --- -[[rust-analyzer.imports.prefix]]rust-analyzer.imports.prefix (default: `"plain"`):: -+ --- -The path structure for newly inserted paths to use. --- -[[rust-analyzer.inlayHints.bindingModeHints.enable]]rust-analyzer.inlayHints.bindingModeHints.enable (default: `false`):: -+ --- -Whether to show inlay type hints for binding modes. --- -[[rust-analyzer.inlayHints.chainingHints.enable]]rust-analyzer.inlayHints.chainingHints.enable (default: `true`):: -+ --- -Whether to show inlay type hints for method chains. --- -[[rust-analyzer.inlayHints.closingBraceHints.enable]]rust-analyzer.inlayHints.closingBraceHints.enable (default: `true`):: -+ --- -Whether to show inlay hints after a closing `}` to indicate what item it belongs to. --- -[[rust-analyzer.inlayHints.closingBraceHints.minLines]]rust-analyzer.inlayHints.closingBraceHints.minLines (default: `25`):: -+ --- -Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1 -to always show them). --- -[[rust-analyzer.inlayHints.closureCaptureHints.enable]]rust-analyzer.inlayHints.closureCaptureHints.enable (default: `false`):: -+ --- -Whether to show inlay hints for closure captures. --- -[[rust-analyzer.inlayHints.closureReturnTypeHints.enable]]rust-analyzer.inlayHints.closureReturnTypeHints.enable (default: `"never"`):: -+ --- -Whether to show inlay type hints for return types of closures. --- -[[rust-analyzer.inlayHints.closureStyle]]rust-analyzer.inlayHints.closureStyle (default: `"impl_fn"`):: -+ --- -Closure notation in type and chaining inlay hints. --- -[[rust-analyzer.inlayHints.discriminantHints.enable]]rust-analyzer.inlayHints.discriminantHints.enable (default: `"never"`):: -+ --- -Whether to show enum variant discriminant hints. --- -[[rust-analyzer.inlayHints.expressionAdjustmentHints.enable]]rust-analyzer.inlayHints.expressionAdjustmentHints.enable (default: `"never"`):: -+ --- -Whether to show inlay hints for type adjustments. --- -[[rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe]]rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe (default: `false`):: -+ --- -Whether to hide inlay hints for type adjustments outside of `unsafe` blocks. --- -[[rust-analyzer.inlayHints.expressionAdjustmentHints.mode]]rust-analyzer.inlayHints.expressionAdjustmentHints.mode (default: `"prefix"`):: -+ --- -Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc). --- -[[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`):: -+ --- -Whether to show inlay type hints for elided lifetimes in function signatures. --- -[[rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames]]rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames (default: `false`):: -+ --- -Whether to prefer using parameter names as the name for elided lifetime hints if possible. --- -[[rust-analyzer.inlayHints.maxLength]]rust-analyzer.inlayHints.maxLength (default: `25`):: -+ --- -Maximum length for inlay hints. Set to null to have an unlimited length. --- -[[rust-analyzer.inlayHints.parameterHints.enable]]rust-analyzer.inlayHints.parameterHints.enable (default: `true`):: -+ --- -Whether to show function parameter name inlay hints at the call -site. --- -[[rust-analyzer.inlayHints.reborrowHints.enable]]rust-analyzer.inlayHints.reborrowHints.enable (default: `"never"`):: -+ --- -Whether to show inlay hints for compiler inserted reborrows. -This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#. --- -[[rust-analyzer.inlayHints.renderColons]]rust-analyzer.inlayHints.renderColons (default: `true`):: -+ --- -Whether to render leading colons for type hints, and trailing colons for parameter hints. --- -[[rust-analyzer.inlayHints.typeHints.enable]]rust-analyzer.inlayHints.typeHints.enable (default: `true`):: -+ --- -Whether to show inlay type hints for variables. --- -[[rust-analyzer.inlayHints.typeHints.hideClosureInitialization]]rust-analyzer.inlayHints.typeHints.hideClosureInitialization (default: `false`):: -+ --- -Whether to hide inlay type hints for `let` statements that initialize to a closure. -Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`. --- -[[rust-analyzer.inlayHints.typeHints.hideNamedConstructor]]rust-analyzer.inlayHints.typeHints.hideNamedConstructor (default: `false`):: -+ --- -Whether to hide inlay type hints for constructors. --- -[[rust-analyzer.interpret.tests]]rust-analyzer.interpret.tests (default: `false`):: -+ --- -Enables the experimental support for interpreting tests. --- -[[rust-analyzer.joinLines.joinAssignments]]rust-analyzer.joinLines.joinAssignments (default: `true`):: -+ --- -Join lines merges consecutive declaration and initialization of an assignment. --- -[[rust-analyzer.joinLines.joinElseIf]]rust-analyzer.joinLines.joinElseIf (default: `true`):: -+ --- -Join lines inserts else between consecutive ifs. --- -[[rust-analyzer.joinLines.removeTrailingComma]]rust-analyzer.joinLines.removeTrailingComma (default: `true`):: -+ --- -Join lines removes trailing commas. --- -[[rust-analyzer.joinLines.unwrapTrivialBlock]]rust-analyzer.joinLines.unwrapTrivialBlock (default: `true`):: -+ --- -Join lines unwraps trivial blocks. --- -[[rust-analyzer.lens.debug.enable]]rust-analyzer.lens.debug.enable (default: `true`):: -+ --- -Whether to show `Debug` lens. Only applies when -`#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.lens.enable]]rust-analyzer.lens.enable (default: `true`):: -+ --- -Whether to show CodeLens in Rust files. --- -[[rust-analyzer.lens.forceCustomCommands]]rust-analyzer.lens.forceCustomCommands (default: `true`):: -+ --- -Internal config: use custom client-side commands even when the -client doesn't set the corresponding capability. --- -[[rust-analyzer.lens.implementations.enable]]rust-analyzer.lens.implementations.enable (default: `true`):: -+ --- -Whether to show `Implementations` lens. Only applies when -`#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.lens.location]]rust-analyzer.lens.location (default: `"above_name"`):: -+ --- -Where to render annotations. --- -[[rust-analyzer.lens.references.adt.enable]]rust-analyzer.lens.references.adt.enable (default: `false`):: -+ --- -Whether to show `References` lens for Struct, Enum, and Union. -Only applies when `#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.lens.references.enumVariant.enable]]rust-analyzer.lens.references.enumVariant.enable (default: `false`):: -+ --- -Whether to show `References` lens for Enum Variants. -Only applies when `#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.lens.references.method.enable]]rust-analyzer.lens.references.method.enable (default: `false`):: -+ --- -Whether to show `Method References` lens. Only applies when -`#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.lens.references.trait.enable]]rust-analyzer.lens.references.trait.enable (default: `false`):: -+ --- -Whether to show `References` lens for Trait. -Only applies when `#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.lens.run.enable]]rust-analyzer.lens.run.enable (default: `true`):: -+ --- -Whether to show `Run` lens. Only applies when -`#rust-analyzer.lens.enable#` is set. --- -[[rust-analyzer.linkedProjects]]rust-analyzer.linkedProjects (default: `[]`):: -+ --- -Disable project auto-discovery in favor of explicitly specified set -of projects. - -Elements must be paths pointing to `Cargo.toml`, -`rust-project.json`, or JSON objects in `rust-project.json` format. --- -[[rust-analyzer.lru.capacity]]rust-analyzer.lru.capacity (default: `null`):: -+ --- -Number of syntax trees rust-analyzer keeps in memory. Defaults to 128. --- -[[rust-analyzer.lru.query.capacities]]rust-analyzer.lru.query.capacities (default: `{}`):: -+ --- -Sets the LRU capacity of the specified queries. --- -[[rust-analyzer.notifications.cargoTomlNotFound]]rust-analyzer.notifications.cargoTomlNotFound (default: `true`):: -+ --- -Whether to show `can't find Cargo.toml` error message. --- -[[rust-analyzer.numThreads]]rust-analyzer.numThreads (default: `null`):: -+ --- -How many worker threads in the main loop. The default `null` means to pick automatically. --- -[[rust-analyzer.procMacro.attributes.enable]]rust-analyzer.procMacro.attributes.enable (default: `true`):: -+ --- -Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. --- -[[rust-analyzer.procMacro.enable]]rust-analyzer.procMacro.enable (default: `true`):: -+ --- -Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. --- -[[rust-analyzer.procMacro.ignored]]rust-analyzer.procMacro.ignored (default: `{}`):: -+ --- -These proc-macros will be ignored when trying to expand them. - -This config takes a map of crate names with the exported proc-macro names to ignore as values. --- -[[rust-analyzer.procMacro.server]]rust-analyzer.procMacro.server (default: `null`):: -+ --- -Internal config, path to proc-macro server executable. --- -[[rust-analyzer.references.excludeImports]]rust-analyzer.references.excludeImports (default: `false`):: -+ --- -Exclude imports from find-all-references. --- -[[rust-analyzer.runnables.command]]rust-analyzer.runnables.command (default: `null`):: -+ --- -Command to be executed instead of 'cargo' for runnables. --- -[[rust-analyzer.runnables.extraArgs]]rust-analyzer.runnables.extraArgs (default: `[]`):: -+ --- -Additional arguments to be passed to cargo for runnables such as -tests or binaries. For example, it may be `--release`. --- -[[rust-analyzer.rust.analyzerTargetDir]]rust-analyzer.rust.analyzerTargetDir (default: `null`):: -+ --- -Optional path to a rust-analyzer specific target directory. -This prevents rust-analyzer's `cargo check` 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. --- -[[rust-analyzer.rustc.source]]rust-analyzer.rustc.source (default: `null`):: -+ --- -Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private -projects, or "discover" to try to automatically find it if the `rustc-dev` component -is installed. - -Any project which uses rust-analyzer with the rustcPrivate -crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. - -This option does not take effect until rust-analyzer is restarted. --- -[[rust-analyzer.rustfmt.extraArgs]]rust-analyzer.rustfmt.extraArgs (default: `[]`):: -+ --- -Additional arguments to `rustfmt`. --- -[[rust-analyzer.rustfmt.overrideCommand]]rust-analyzer.rustfmt.overrideCommand (default: `null`):: -+ --- -Advanced option, fully override the command rust-analyzer uses for -formatting. This should be the equivalent of `rustfmt` here, and -not that of `cargo fmt`. The file contents will be passed on the -standard input and the formatted result will be read from the -standard output. --- -[[rust-analyzer.rustfmt.rangeFormatting.enable]]rust-analyzer.rustfmt.rangeFormatting.enable (default: `false`):: -+ --- -Enables the use of rustfmt's unstable range formatting command for the -`textDocument/rangeFormatting` request. The rustfmt option is unstable and only -available on a nightly build. --- -[[rust-analyzer.semanticHighlighting.doc.comment.inject.enable]]rust-analyzer.semanticHighlighting.doc.comment.inject.enable (default: `true`):: -+ --- -Inject additional highlighting into doc comments. - -When enabled, rust-analyzer will highlight rust source in doc comments as well as intra -doc links. --- -[[rust-analyzer.semanticHighlighting.nonStandardTokens]]rust-analyzer.semanticHighlighting.nonStandardTokens (default: `true`):: -+ --- -Whether the server is allowed to emit non-standard tokens and modifiers. --- -[[rust-analyzer.semanticHighlighting.operator.enable]]rust-analyzer.semanticHighlighting.operator.enable (default: `true`):: -+ --- -Use semantic tokens for operators. - -When disabled, rust-analyzer will emit semantic tokens only for operator tokens when -they are tagged with modifiers. --- -[[rust-analyzer.semanticHighlighting.operator.specialization.enable]]rust-analyzer.semanticHighlighting.operator.specialization.enable (default: `false`):: -+ --- -Use specialized semantic tokens for operators. - -When enabled, rust-analyzer will emit special token types for operator tokens instead -of the generic `operator` token type. --- -[[rust-analyzer.semanticHighlighting.punctuation.enable]]rust-analyzer.semanticHighlighting.punctuation.enable (default: `false`):: -+ --- -Use semantic tokens for punctuation. - -When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when -they are tagged with modifiers or have a special role. --- -[[rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang]]rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang (default: `false`):: -+ --- -When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro -calls. --- -[[rust-analyzer.semanticHighlighting.punctuation.specialization.enable]]rust-analyzer.semanticHighlighting.punctuation.specialization.enable (default: `false`):: -+ --- -Use specialized semantic tokens for punctuation. - -When enabled, rust-analyzer will emit special token types for punctuation tokens instead -of the generic `punctuation` token type. --- -[[rust-analyzer.semanticHighlighting.strings.enable]]rust-analyzer.semanticHighlighting.strings.enable (default: `true`):: -+ --- -Use semantic tokens for strings. - -In some editors (e.g. vscode) semantic tokens override other highlighting grammars. -By disabling semantic tokens for strings, other grammars can be used to highlight -their contents. --- -[[rust-analyzer.signatureInfo.detail]]rust-analyzer.signatureInfo.detail (default: `"full"`):: -+ --- -Show full signature of the callable. Only shows parameters if disabled. --- -[[rust-analyzer.signatureInfo.documentation.enable]]rust-analyzer.signatureInfo.documentation.enable (default: `true`):: -+ --- -Show documentation. --- -[[rust-analyzer.typing.autoClosingAngleBrackets.enable]]rust-analyzer.typing.autoClosingAngleBrackets.enable (default: `false`):: -+ --- -Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list. --- -[[rust-analyzer.workspace.symbol.search.kind]]rust-analyzer.workspace.symbol.search.kind (default: `"only_types"`):: -+ --- -Workspace symbol search kind. --- -[[rust-analyzer.workspace.symbol.search.limit]]rust-analyzer.workspace.symbol.search.limit (default: `128`):: -+ --- -Limits the number of items returned from a workspace symbol search (Defaults to 128). -Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search. -Other clients requires all results upfront and might require a higher limit. --- -[[rust-analyzer.workspace.symbol.search.scope]]rust-analyzer.workspace.symbol.search.scope (default: `"workspace"`):: -+ --- -Workspace symbol search scope. --- diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc deleted file mode 100644 index 18d5ddd4d0af..000000000000 --- a/docs/user/manual.adoc +++ /dev/null @@ -1,1017 +0,0 @@ -= User Manual -:toc: preamble -:sectanchors: -:page-layout: post -:icons: font -:source-highlighter: rouge -:experimental: - -//// -IMPORTANT: the master copy of this document lives in the https://github.com/rust-lang/rust-analyzer repository -//// - -At its core, rust-analyzer is a *library* for semantic analysis of Rust code as it changes over time. -This manual focuses on a specific usage of the library -- running it as part of a server that implements the -https://microsoft.github.io/language-server-protocol/[Language Server Protocol] (LSP). -The LSP allows various code editors, like VS Code, Emacs or Vim, to implement semantic features like completion or goto definition by talking to an external language server process. - -[TIP] -==== -[.lead] -To improve this document, send a pull request: + -https://github.com/rust-lang/rust-analyzer/blob/master/docs/user/manual.adoc[https://github.com/rust-analyzer/.../manual.adoc] - -The manual is written in https://asciidoc.org[AsciiDoc] and includes some extra files which are generated from the source code. Run `cargo test` and `cargo test -p xtask` to create these and then `asciidoctor manual.adoc` to create an HTML copy. -==== - -If you have questions about using rust-analyzer, please ask them in the https://users.rust-lang.org/c/ide/14["`IDEs and Editors`"] topic of Rust users forum. - -== Installation - -In theory, one should be able to just install the <> and have it automatically work with any editor. -We are not there yet, so some editor specific setup is required. - -Additionally, rust-analyzer needs the sources of the standard library. -If the source code is not present, rust-analyzer will attempt to install it automatically. - -To add the sources manually, run the following command: - -```bash -$ rustup component add rust-src -``` - -=== Toolchain - -Only the latest stable standard library source is officially supported for use with rust-analyzer. -If you are using an older toolchain or have an override set, rust-analyzer may fail to understand the Rust source. -You will either need to update your toolchain or use an older version of rust-analyzer that is compatible with your toolchain. - -If you are using an override in your project, you can still force rust-analyzer to use the stable toolchain via the environment variable `RUSTUP_TOOLCHAIN`. -For example, with VS Code or coc-rust-analyzer: - -[source,json] ----- -{ "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "stable" } } ----- - -=== VS Code - -This is the best supported editor at the moment. -The rust-analyzer plugin for VS Code is maintained -https://github.com/rust-lang/rust-analyzer/tree/master/editors/code[in tree]. - -You can install the latest release of the plugin from -https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer[the marketplace]. - -Note that the plugin may cause conflicts with the -https://marketplace.visualstudio.com/items?itemName=rust-lang.rust[previous official Rust plugin]. -The latter is no longer maintained and should be uninstalled. - -The server binary is stored in the extension install directory, which starts with `rust-lang.rust-analyzer-` and is located under: - -* Linux: `~/.vscode/extensions` -* Linux (Remote, such as WSL): `~/.vscode-server/extensions` -* macOS: `~/.vscode/extensions` -* Windows: `%USERPROFILE%\.vscode\extensions` - -As an exception, on NixOS, the extension makes a copy of the server and stores it under `~/.config/Code/User/globalStorage/rust-lang.rust-analyzer`. - -Note that we only support the two most recent versions of VS Code. - -==== Updates - -The extension will be updated automatically as new versions become available. -It will ask your permission to download the matching language server version binary if needed. - -===== Nightly - -We ship nightly releases for VS Code. -To help us out by testing the newest code, you can enable pre-release versions in the Code extension page. - -==== Manual installation - -Alternatively, download a VSIX corresponding to your platform from the -https://github.com/rust-lang/rust-analyzer/releases[releases] page. - -Install the extension with the `Extensions: Install from VSIX` command within VS Code, or from the command line via: -[source] ----- -$ code --install-extension /path/to/rust-analyzer.vsix ----- - -If you are running an unsupported platform, you can install `rust-analyzer-no-server.vsix` and compile or obtain a server binary. -Copy the server anywhere, then add the path to your settings.json, for example: -[source,json] ----- -{ "rust-analyzer.server.path": "~/.local/bin/rust-analyzer-linux" } ----- - -==== Building From Source - -Both the server and the Code plugin can be installed from source: - -[source] ----- -$ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer -$ cargo xtask install ----- - -You'll need Cargo, nodejs (matching a supported version of VS Code) and npm for this. - -Note that installing via `xtask install` does not work for VS Code Remote, instead you'll need to install the `.vsix` manually. - -If you're not using Code, you can compile and install only the LSP server: - -[source] ----- -$ cargo xtask install --server ----- - -Make sure that `.cargo/bin` is in `$PATH` and precedes paths where `rust-analyzer` may also be installed. -Specifically, `rustup` includes a proxy called `rust-analyzer`, which can cause problems if you're planning to use a source build or even a downloaded binary. - -=== rust-analyzer Language Server Binary - -Other editors generally require the `rust-analyzer` binary to be in `$PATH`. -You can download pre-built binaries from the https://github.com/rust-lang/rust-analyzer/releases[releases] page. -You will need to uncompress and rename the binary for your platform, e.g. from `rust-analyzer-aarch64-apple-darwin.gz` on Mac OS to `rust-analyzer`, make it executable, then move it into a directory in your `$PATH`. - -On Linux to install the `rust-analyzer` binary into `~/.local/bin`, these commands should work: - -[source,bash] ----- -$ mkdir -p ~/.local/bin -$ curl -L https://github.com/rust-lang/rust-analyzer/releases/latest/download/rust-analyzer-x86_64-unknown-linux-gnu.gz | gunzip -c - > ~/.local/bin/rust-analyzer -$ chmod +x ~/.local/bin/rust-analyzer ----- - -Make sure that `~/.local/bin` is listed in the `$PATH` variable and use the appropriate URL if you're not on a `x86-64` system. - -You don't have to use `~/.local/bin`, any other path like `~/.cargo/bin` or `/usr/local/bin` will work just as well. - -Alternatively, you can install it from source using the command below. -You'll need the latest stable version of the Rust toolchain. - -[source,bash] ----- -$ git clone https://github.com/rust-lang/rust-analyzer.git && cd rust-analyzer -$ cargo xtask install --server ----- - -If your editor can't find the binary even though the binary is on your `$PATH`, the likely explanation is that it doesn't see the same `$PATH` as the shell, see https://github.com/rust-lang/rust-analyzer/issues/1811[this issue]. -On Unix, running the editor from a shell or changing the `.desktop` file to set the environment should help. - -==== rustup - -`rust-analyzer` is available in `rustup`: - -[source,bash] ----- -$ rustup component add rust-analyzer ----- - -==== Arch Linux - -The `rust-analyzer` binary can be installed from the repos or AUR (Arch User Repository): - -- https://www.archlinux.org/packages/community/x86_64/rust-analyzer/[`rust-analyzer`] (built from latest tagged source) -- https://aur.archlinux.org/packages/rust-analyzer-git[`rust-analyzer-git`] (latest Git version) - -Install it with pacman, for example: - -[source,bash] ----- -$ pacman -S rust-analyzer ----- - -==== Gentoo Linux - -`rust-analyzer` is available in the GURU repository: - -- https://gitweb.gentoo.org/repo/proj/guru.git/tree/dev-util/rust-analyzer?id=9895cea62602cfe599bd48e0fb02127411ca6e81[`dev-util/rust-analyzer`] builds from source -- https://gitweb.gentoo.org/repo/proj/guru.git/tree/dev-util/rust-analyzer-bin?id=9895cea62602cfe599bd48e0fb02127411ca6e81[`dev-util/rust-analyzer-bin`] installs an official binary release - -If not already, GURU must be enabled (e.g. using `app-eselect/eselect-repository`) and sync'd before running `emerge`: - -[source,bash] ----- -$ eselect repository enable guru && emaint sync -r guru -$ emerge rust-analyzer-bin ----- - -==== macOS - -The `rust-analyzer` binary can be installed via https://brew.sh/[Homebrew]. - -[source,bash] ----- -$ brew install rust-analyzer ----- - -=== VS Code or VSCodium in Flatpak - -Setting up `rust-analyzer` with a Flatpak version of Code is not trivial because of the Flatpak sandbox. -While the sandbox can be disabled for some directories, `/usr/bin` will always be mounted under `/run/host/usr/bin`. -This prevents access to the system's C compiler, a system-wide installation of Rust, or any other libraries you might want to link to. -Some compilers and libraries can be acquired as Flatpak SDKs, such as `org.freedesktop.Sdk.Extension.rust-stable` or `org.freedesktop.Sdk.Extension.llvm15`. - -If you use a Flatpak SDK for Rust, there should be no extra steps necessary. - -If you want to use Flatpak in combination with `rustup`, the following steps might help: - - - both Rust and `rustup` have to be installed using https://rustup.rs. Distro packages _will not_ work. - - you need to launch Code, open a terminal and run `echo $PATH` - - using https://flathub.org/apps/details/com.github.tchx84.Flatseal[Flatseal], you must add an environment variable called `PATH`. - Set its value to the output from above, appending `:~/.cargo/bin`, where `~` is the path to your home directory. - You must replace `~`, as it won't be expanded otherwise. - - while Flatseal is open, you must enable access to "All user files" - -A C compiler should already be available via `org.freedesktop.Sdk`. -Any other tools or libraries you will need to acquire from Flatpak. - -=== Emacs - -Prerequisites: You have installed the <>. - -To use `rust-analyzer`, you need to install and enable one of the two popular LSP client implementations for Emacs, https://github.com/joaotavora/eglot[Eglot] or https://github.com/emacs-lsp/lsp-mode[LSP Mode]. Both enable `rust-analyzer` by default in rust buffers if it is available. - -==== Eglot - -Eglot is the more minimalistic and lightweight LSP client for Emacs, integrates well with existing Emacs functionality and is built into Emacs starting from release 29. - -After installing Eglot, e.g. via `M-x package-install` (not needed from Emacs 29), you can enable it via the `M-x eglot` command or load it automatically in `rust-mode` via - -[source,emacs-lisp] ----- -(add-hook 'rust-mode-hook 'eglot-ensure) ----- - -To enable clippy, you will need to configure the initialization options to pass the `check.command` setting. - -[source,emacs-lisp] ----- -(add-to-list 'eglot-server-programs - '((rust-ts-mode rust-mode) . - ("rust-analyzer" :initializationOptions (:check (:command "clippy"))))) ----- - -For more detailed instructions and options see the https://joaotavora.github.io/eglot[Eglot manual] (also available from Emacs via `M-x info`) and the -https://github.com/joaotavora/eglot/blob/master/README.md[Eglot readme]. - -Eglot does not support the rust-analyzer extensions to the language-server protocol and does not aim to do so in the future. The https://github.com/nemethf/eglot-x#rust-analyzer-extensions[eglot-x] package adds experimental support for those LSP extensions. - -==== LSP Mode - -LSP-mode is the original LSP-client for emacs. Compared to Eglot it has a larger codebase and supports more features, like LSP protocol extensions. -With extension packages like https://github.com/emacs-lsp/lsp-mode[LSP UI] it offers a lot of visual eyecandy. -Further it integrates well with https://github.com/emacs-lsp/dap-mode[DAP mode] for support of the Debug Adapter Protocol. - -You can install LSP-mode via `M-x package-install` and then run it via the `M-x lsp` command or load it automatically in rust buffers with - -[source,emacs-lisp] ----- -(add-hook 'rust-mode-hook 'lsp-deferred) ----- - -For more information on how to set up LSP mode and its extension package see the instructions in the https://emacs-lsp.github.io/lsp-mode/page/installation[LSP mode manual]. -Also see the https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/[rust-analyzer section] for `rust-analyzer` specific options and commands, which you can optionally bind to keys. - -Note the excellent https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/[guide] from https://github.com/rksm[@rksm] on how to set-up Emacs for Rust development with LSP mode and several other packages. - -=== Vim/Neovim - -Prerequisites: You have installed the <>. -Not needed if the extension can install/update it on its own, coc-rust-analyzer is one example. - -There are several LSP client implementations for Vim or Neovim: - -==== coc-rust-analyzer - -1. Install coc.nvim by following the instructions at - https://github.com/neoclide/coc.nvim[coc.nvim] - (Node.js required) -2. Run `:CocInstall coc-rust-analyzer` to install - https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer], - this extension implements _most_ of the features supported in the VSCode extension: - * automatically install and upgrade stable/nightly releases - * same configurations as VSCode extension, `rust-analyzer.server.path`, `rust-analyzer.cargo.features` etc. - * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.ssr` etc. - * inlay hints for variables and method chaining, _Neovim Only_ - -Note: for code actions, use `coc-codeaction-cursor` and `coc-codeaction-selected`; `coc-codeaction` and `coc-codeaction-line` are unlikely to be useful. - -==== LanguageClient-neovim - -1. Install LanguageClient-neovim by following the instructions - https://github.com/autozimu/LanguageClient-neovim[here] - * The GitHub project wiki has extra tips on configuration - -2. Configure by adding this to your Vim/Neovim config file (replacing the existing Rust-specific line if it exists): -+ -[source,vim] ----- -let g:LanguageClient_serverCommands = { -\ 'rust': ['rust-analyzer'], -\ } ----- - -==== YouCompleteMe - -Install YouCompleteMe by following the instructions - https://github.com/ycm-core/YouCompleteMe#installation[here]. - -rust-analyzer is the default in ycm, it should work out of the box. - -==== ALE - -To use the LSP server in https://github.com/dense-analysis/ale[ale]: - -[source,vim] ----- -let g:ale_linters = {'rust': ['analyzer']} ----- - -==== nvim-lsp - -Neovim 0.5 has built-in language server support. -For a quick start configuration of rust-analyzer, use https://github.com/neovim/nvim-lspconfig#rust_analyzer[neovim/nvim-lspconfig]. -Once `neovim/nvim-lspconfig` is installed, use `+lua require'lspconfig'.rust_analyzer.setup({})+` in your `init.vim`. - -You can also pass LSP settings to the server: - -[source,vim] ----- -lua << EOF -local nvim_lsp = require'lspconfig' - -local on_attach = function(client) - require'completion'.on_attach(client) -end - -nvim_lsp.rust_analyzer.setup({ - on_attach=on_attach, - settings = { - ["rust-analyzer"] = { - imports = { - granularity = { - group = "module", - }, - prefix = "self", - }, - cargo = { - buildScripts = { - enable = true, - }, - }, - procMacro = { - enable = true - }, - } - } -}) -EOF ----- - -See https://sharksforarms.dev/posts/neovim-rust/ for more tips on getting started. - -Check out https://github.com/simrat39/rust-tools.nvim for a batteries included rust-analyzer setup for Neovim. - -==== vim-lsp - -vim-lsp is installed by following https://github.com/prabirshrestha/vim-lsp[the plugin instructions]. -It can be as simple as adding this line to your `.vimrc`: - -[source,vim] ----- -Plug 'prabirshrestha/vim-lsp' ----- - -Next you need to register the `rust-analyzer` binary. -If it is available in `$PATH`, you may want to add this to your `.vimrc`: - -[source,vim] ----- -if executable('rust-analyzer') - au User lsp_setup call lsp#register_server({ - \ 'name': 'Rust Language Server', - \ 'cmd': {server_info->['rust-analyzer']}, - \ 'whitelist': ['rust'], - \ }) -endif ----- - -There is no dedicated UI for the server configuration, so you would need to send any options as a value of the `initialization_options` field, as described in the <> section. -Here is an example of how to enable the proc-macro support: - -[source,vim] ----- -if executable('rust-analyzer') - au User lsp_setup call lsp#register_server({ - \ 'name': 'Rust Language Server', - \ 'cmd': {server_info->['rust-analyzer']}, - \ 'whitelist': ['rust'], - \ 'initialization_options': { - \ 'cargo': { - \ 'buildScripts': { - \ 'enable': v:true, - \ }, - \ }, - \ 'procMacro': { - \ 'enable': v:true, - \ }, - \ }, - \ }) -endif ----- - -=== Sublime Text - -==== Sublime Text 4: -* Follow the instructions in link:https://github.com/sublimelsp/LSP-rust-analyzer[LSP-rust-analyzer]. - -NOTE: Install link:https://packagecontrol.io/packages/LSP-file-watcher-chokidar[LSP-file-watcher-chokidar] to enable file watching (`workspace/didChangeWatchedFiles`). - -==== Sublime Text 3: -* Install the <>. -* Install the link:https://packagecontrol.io/packages/LSP[LSP package]. -* From the command palette, run `LSP: Enable Language Server Globally` and select `rust-analyzer`. - -If it worked, you should see "rust-analyzer, Line X, Column Y" on the left side of the status bar, and after waiting a bit, functionalities like tooltips on hovering over variables should become available. - -If you get an error saying `No such file or directory: 'rust-analyzer'`, see the <> section on installing the language server binary. - -=== GNOME Builder - -GNOME Builder 3.37.1 and newer has native `rust-analyzer` support. -If the LSP binary is not available, GNOME Builder can install it when opening a Rust file. - - -=== Eclipse IDE - -Support for Rust development in the Eclipse IDE is provided by link:https://github.com/eclipse/corrosion[Eclipse Corrosion]. -If available in PATH or in some standard location, `rust-analyzer` is detected and powers editing of Rust files without further configuration. -If `rust-analyzer` is not detected, Corrosion will prompt you for configuration of your Rust toolchain and language server with a link to the __Window > Preferences > Rust__ preference page; from here a button allows to download and configure `rust-analyzer`, but you can also reference another installation. -You'll need to close and reopen all .rs and Cargo files, or to restart the IDE, for this change to take effect. - -=== Kate Text Editor - -Support for the language server protocol is built into Kate through the LSP plugin, which is included by default. -It is preconfigured to use rust-analyzer for Rust sources since Kate 21.12. - -To change rust-analyzer config options, start from the following example and put it into Kate's "User Server Settings" tab (located under the LSP Client settings): -[source,json] ----- -{ - "servers": { - "rust": { - "initializationOptions": { - "cachePriming": { - "enable": false - }, - "check": { - "allTargets": false - }, - "checkOnSave": false - } - } - } -} ----- -Then click on apply, and restart the LSP server for your rust project. - -=== juCi++ - -https://gitlab.com/cppit/jucipp[juCi++] has built-in support for the language server protocol, and since version 1.7.0 offers installation of both Rust and rust-analyzer when opening a Rust file. - -=== Kakoune - -https://kakoune.org/[Kakoune] supports LSP with the help of https://github.com/kak-lsp/kak-lsp[`kak-lsp`]. -Follow the https://github.com/kak-lsp/kak-lsp#installation[instructions] to install `kak-lsp`. -To configure `kak-lsp`, refer to the https://github.com/kak-lsp/kak-lsp#configuring-kak-lsp[configuration section] which is basically about copying the https://github.com/kak-lsp/kak-lsp/blob/master/kak-lsp.toml[configuration file] in the right place (latest versions should use `rust-analyzer` by default). - -Finally, you need to configure Kakoune to talk to `kak-lsp` (see https://github.com/kak-lsp/kak-lsp#usage[Usage section]). -A basic configuration will only get you LSP but you can also activate inlay diagnostics and auto-formatting on save. -The following might help you get all of this. - -[source,txt] ----- -eval %sh{kak-lsp --kakoune -s $kak_session} # Not needed if you load it with plug.kak. -hook global WinSetOption filetype=rust %{ - # Enable LSP - lsp-enable-window - - # Auto-formatting on save - hook window BufWritePre .* lsp-formatting-sync - - # Configure inlay hints (only on save) - hook window -group rust-inlay-hints BufWritePost .* rust-analyzer-inlay-hints - hook -once -always window WinSetOption filetype=.* %{ - remove-hooks window rust-inlay-hints - } -} ----- - -=== Helix - -https://docs.helix-editor.com/[Helix] supports LSP by default. -However, it won't install `rust-analyzer` automatically. -You can follow instructions for installing <>. - -=== Visual Studio 2022 - -There are multiple rust-analyzer extensions for Visual Studio 2022 on Windows: - -==== rust-analyzer.vs - -(License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International) - -https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer[Visual Studio Marketplace] - -https://github.com/kitamstudios/rust-analyzer/[GitHub] - -Support for Rust development in the Visual Studio IDE is enabled by the link:https://marketplace.visualstudio.com/items?itemName=kitamstudios.RustAnalyzer[rust-analyzer] package. Either click on the download link or install from IDE's extension manager. -For now link:https://visualstudio.microsoft.com/downloads/[Visual Studio 2022] is required. All editions are supported viz. Community, Professional & Enterprise. -The package aims to provide 0-friction installation and therefore comes loaded with most things required including rust-analyzer binary. If anything it needs is missing, appropriate errors / warnings will guide the user. E.g. cargo.exe needs to be in path and the package will tell you as much. -This package is under rapid active development. So if you encounter any issues please file it at link:https://github.com/kitamstudios/rust-analyzer/[rust-analyzer.vs]. - -==== VS_RustAnalyzer - -(License: GPL) - -https://marketplace.visualstudio.com/items?itemName=cchharris.vsrustanalyzer[Visual Studio Marketplace] - -https://github.com/cchharris/VS-RustAnalyzer[GitHub] - -==== SourceGear Rust - -(License: closed source) - -https://marketplace.visualstudio.com/items?itemName=SourceGear.SourceGearRust[Visual Studio Marketplace] - -https://github.com/sourcegear/rust-vs-extension[GitHub (docs, issues, discussions)] - -* Free (no-cost) -* Supports all editions of Visual Studio 2022 on Windows: Community, Professional, or Enterprise - -=== Lapce - -https://lapce.dev/[Lapce] has a Rust plugin which you can install directly. -Unfortunately, it downloads an old version of `rust-analyzer`, but you can set the server path under Settings. - -=== Crates - -There is a package named `ra_ap_rust_analyzer` available on https://crates.io/crates/ra_ap_rust-analyzer[crates.io], for someone who wants to use it programmatically. - -For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml[the publish workflow]. - -=== Zed - -https://zed.dev[Zed] has native `rust-analyzer` support. -If the LSP binary is not available, Zed can install it when opening a Rust file. - -== Troubleshooting - -Start with looking at the rust-analyzer version. -Try **rust-analyzer: Show RA Version** in VS Code (using **Command Palette** feature typically activated by Ctrl+Shift+P) or `rust-analyzer --version` in the command line. -If the date is more than a week ago, it's better to update rust-analyzer version. - -The next thing to check would be panic messages in rust-analyzer's log. -Log messages are printed to stderr, in VS Code you can see them in the `Output > Rust Analyzer Language Server` tab of the panel. -To see more logs, set the `RA_LOG=info` environment variable, this can be done either by setting the environment variable manually or by using `rust-analyzer.server.extraEnv`, note that both of these approaches require the server to be restarted. - -To fully capture LSP messages between the editor and the server, set `"rust-analyzer.trace.server": "verbose"` config and check -`Output > Rust Analyzer Language Server Trace`. - -The root cause for many "`nothing works`" problems is that rust-analyzer fails to understand the project structure. -To debug that, first note the `rust-analyzer` section in the status bar. -If it has an error icon and red, that's the problem (hover will have somewhat helpful error message). -**rust-analyzer: Status** prints dependency information for the current file. -Finally, `RA_LOG=project_model=debug` enables verbose logs during project loading. - -If rust-analyzer outright crashes, try running `rust-analyzer analysis-stats /path/to/project/directory/` on the command line. -This command type checks the whole project in batch mode bypassing LSP machinery. - -When filing issues, it is useful (but not necessary) to try to minimize examples. -An ideal bug reproduction looks like this: - -```bash -$ git clone https://github.com/username/repo.git && cd repo && git switch --detach commit-hash -$ rust-analyzer --version -rust-analyzer dd12184e4 2021-05-08 dev -$ rust-analyzer analysis-stats . -💀 💀 💀 -``` - -It is especially useful when the `repo` doesn't use external crates or the standard library. - -If you want to go as far as to modify the source code to debug the problem, be sure to take a look at the -https://github.com/rust-lang/rust-analyzer/tree/master/docs/dev[dev docs]! - -== Configuration - -**Source:** https://github.com/rust-lang/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs] - -The <<_installation,Installation>> section contains details on configuration for some of the editors. -In general `rust-analyzer` is configured via LSP messages, which means that it's up to the editor to decide on the exact format and location of configuration files. - -Some clients, such as <> or <> provide `rust-analyzer` specific configuration UIs. Others may require you to know a bit more about the interaction with `rust-analyzer`. - -For the later category, it might help to know that the initial configuration is specified as a value of the `initializationOptions` field of the https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize[`InitializeParams` message, in the LSP protocol]. -The spec says that the field type is `any?`, but `rust-analyzer` is looking for a JSON object that is constructed using settings from the list below. -Name of the setting, ignoring the `rust-analyzer.` prefix, is used as a path, and value of the setting becomes the JSON property value. - -For example, a very common configuration is to enable proc-macro support, can be achieved by sending this JSON: - -[source,json] ----- -{ - "cargo": { - "buildScripts": { - "enable": true, - }, - }, - "procMacro": { - "enable": true, - } -} ----- - -Please consult your editor's documentation to learn more about how to configure https://microsoft.github.io/language-server-protocol/[LSP servers]. - -To verify which configuration is actually used by `rust-analyzer`, set `RA_LOG` environment variable to `rust_analyzer=info` and look for config-related messages. -Logs should show both the JSON that `rust-analyzer` sees as well as the updated config. - -This is the list of config options `rust-analyzer` supports: - -include::./generated_config.adoc[] - -== 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 { - /// Path to the sysroot directory. - /// - /// The sysroot is where rustc looks for the - /// crates that are built-in to rust, such as - /// std. - /// - /// https://doc.rust-lang.org/rustc/command-line-arguments.html#--sysroot-override-the-system-root - /// - /// To see the current value of sysroot, you - /// can query rustc: - /// - /// ``` - /// $ rustc --print sysroot - /// /Users/yourname/.rustup/toolchains/stable-x86_64-apple-darwin - /// ``` - sysroot?: string; - /// Path to the directory with *source code* of - /// sysroot crates. - /// - /// By default, this is `lib/rustlib/src/rust/library` - /// relative to the sysroot. - /// - /// It should point to the directory where std, - /// core, and friends can be found: - /// - /// https://github.com/rust-lang/rust/tree/master/library. - /// - /// If provided, rust-analyzer automatically adds - /// dependencies on sysroot crates. Conversely, - /// if you omit this path, you can specify sysroot - /// dependencies yourself and, for example, have - /// several different "sysroots" in one graph of - /// crates. - sysroot_src?: 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 { - /// Optional crate name used for display purposes, - /// without affecting semantics. See the `deps` - /// key for semantically-significant crate names. - display_name?: string; - /// Path to the root module of the crate. - root_module: string; - /// Edition of the crate. - edition: "2015" | "2018" | "2021"; - /// Dependencies - deps: Dep[]; - /// Should this crate be treated as a member of - /// current "workspace". - /// - /// By default, inferred from the `root_module` - /// (members are the crates which reside inside - /// the directory opened in the editor). - /// - /// Set this to `false` for things like standard - /// library and 3rd party crates to enable - /// performance optimizations (rust-analyzer - /// assumes that non-member crates don't change). - is_workspace_member?: boolean; - /// Optionally specify the (super)set of `.rs` - /// files comprising this crate. - /// - /// By default, rust-analyzer assumes that only - /// files under `root_module.parent` can belong - /// to a crate. `include_dirs` are included - /// recursively, unless a subdirectory is in - /// `exclude_dirs`. - /// - /// Different crates can share the same `source`. - /// - /// If two crates share an `.rs` file in common, - /// they *must* have the same `source`. - /// rust-analyzer assumes that files from one - /// source can't refer to files in another source. - source?: { - include_dirs: string[], - exclude_dirs: string[], - }, - /// The set of cfgs activated for a given crate, like - /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`. - cfg: string[]; - /// Target triple for this Crate. - /// - /// Used when running `rustc --print cfg` - /// to get target-specific cfgs. - target?: string; - /// Environment variables, used for - /// the `env!` macro - env: { [key: string]: string; }, - - /// Whether the crate is a proc-macro crate. - is_proc_macro: boolean; - /// For proc-macro crates, path to compiled - /// 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 three ways to feed `rust-project.json` to rust-analyzer: - -* Place `rust-project.json` file at the root of the project, and rust-analyzer 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. - -Relative paths are interpreted relative to `rust-project.json` file location or (for inline JSON) relative to `rootUri`. - -See https://github.com/rust-analyzer/rust-project.json-example for a small example. - -You can set the `RA_LOG` environment variable to `rust_analyzer=info` to inspect how rust-analyzer handles config and project loading. - -Note that calls to `cargo check` are disabled when using `rust-project.json` by default, so compilation errors and warnings will no longer be sent to your LSP client. -To enable these compilation errors you will need to specify explicitly what command rust-analyzer should run to perform the checks using the `rust-analyzer.check.overrideCommand` configuration. -As an example, the following configuration explicitly sets `cargo check` as the `check` command. - -[source,json] ----- -{ "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] } ----- - -`check.overrideCommand` requires the command specified to output json error messages for rust-analyzer to consume. -The `--message-format=json` flag does this for `cargo check` so whichever command you use must also output errors in this format. -See the <> section for more information. - -== Security - -At the moment, rust-analyzer assumes that all code is trusted. -Here is a **non-exhaustive** list of ways to make rust-analyzer execute arbitrary code: - -* proc macros and build scripts are executed by default -* `.cargo/config` can override `rustc` with an arbitrary executable -* `rust-toolchain.toml` can override `rustc` with an arbitrary executable -* VS Code plugin reads configuration from project directory, and that can be used to override paths to various executables, like `rustfmt` or `rust-analyzer` itself. -* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety. - -== Privacy - -The LSP server performs no network access in itself, but runs `cargo metadata` which will update or download the crate registry and the source code of the project dependencies. -If enabled (the default), build scripts and procedural macros can do anything. - -The Code extension does not access the network. - -Any other editor plugins are not under the control of the `rust-analyzer` developers. For any privacy concerns, you should check with their respective developers. - -For `rust-analyzer` developers, `cargo xtask release` uses the GitHub API to put together the release notes. - -== Features - -include::./generated_features.adoc[] - -== Assists (Code Actions) - -Assists, or code actions, are small local refactorings, available in a particular context. -They are usually triggered by a shortcut or by clicking a light bulb icon in the editor. -Cursor position or selection is signified by `┃` character. - -include::./generated_assists.adoc[] - -== Diagnostics - -While most errors and warnings provided by rust-analyzer come from the `cargo check` integration, there's a growing number of diagnostics implemented using rust-analyzer's own analysis. -Some of these diagnostics don't respect `\#[allow]` or `\#[deny]` attributes yet, but can be turned off using the `rust-analyzer.diagnostics.enable`, `rust-analyzer.diagnostics.experimental.enable` or `rust-analyzer.diagnostics.disabled` settings. - -=== Clippy - -To run `cargo clippy` instead of `cargo check`, you can set `"rust-analyzer.check.command": "clippy"`. - -include::./generated_diagnostic.adoc[] - -== Editor Features -=== VS Code - -==== Color configurations - -It is possible to change the foreground/background color and font family/size of inlay hints. -Just add this to your `settings.json`: - -[source,jsonc] ----- -{ - "editor.inlayHints.fontFamily": "Courier New", - "editor.inlayHints.fontSize": 11, - - "workbench.colorCustomizations": { - // Name of the theme you are currently using - "[Default Dark+]": { - "editorInlayHint.foreground": "#868686f0", - "editorInlayHint.background": "#3d3d3d48", - - // Overrides for specific kinds of inlay hints - "editorInlayHint.typeForeground": "#fdb6fdf0", - "editorInlayHint.parameterForeground": "#fdb6fdf0", - } - } -} ----- - -==== Semantic style customizations - -You can customize the look of different semantic elements in the source code. -For example, mutable bindings are underlined by default and you can override this behavior by adding the following section to your `settings.json`: - -[source,jsonc] ----- -{ - "editor.semanticTokenColorCustomizations": { - "rules": { - "*.mutable": { - "fontStyle": "", // underline is the default - }, - } - }, -} ----- - -Most themes doesn't support styling unsafe operations differently yet. You can fix this by adding overrides for the rules `operator.unsafe`, `function.unsafe`, and `method.unsafe`: - -[source,jsonc] ----- -{ - "editor.semanticTokenColorCustomizations": { - "rules": { - "operator.unsafe": "#ff6600", - "function.unsafe": "#ff6600", - "method.unsafe": "#ff6600" - } - }, -} ----- - -In addition to the top-level rules you can specify overrides for specific themes. For example, if you wanted to use a darker text color on a specific light theme, you might write: - -[source,jsonc] ----- -{ - "editor.semanticTokenColorCustomizations": { - "rules": { - "operator.unsafe": "#ff6600" - }, - "[Ayu Light]": { - "rules": { - "operator.unsafe": "#572300" - } - } - }, -} ----- - -Make sure you include the brackets around the theme name. For example, use `"[Ayu Light]"` to customize the theme Ayu Light. - -==== Special `when` clause context for keybindings. -You may use `inRustProject` context to configure keybindings for rust projects only. -For example: - -[source,json] ----- -{ - "key": "ctrl+alt+d", - "command": "rust-analyzer.openDocs", - "when": "inRustProject" -} ----- -More about `when` clause contexts https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts[here]. - -==== Setting runnable environment variables -You can use "rust-analyzer.runnables.extraEnv" setting to define runnable environment-specific substitution variables. -The simplest way for all runnables in a bunch: -```jsonc -"rust-analyzer.runnables.extraEnv": { - "RUN_SLOW_TESTS": "1" -} -``` - -Or it is possible to specify vars more granularly: -```jsonc -"rust-analyzer.runnables.extraEnv": [ - { - // "mask": null, // null mask means that this rule will be applied for all runnables - "env": { - "APP_ID": "1", - "APP_DATA": "asdf" - } - }, - { - "mask": "test_name", - "env": { - "APP_ID": "2", // overwrites only APP_ID - } - } -] -``` - -You can use any valid regular expression as a mask. -Also note that a full runnable name is something like *run bin_or_example_name*, *test some::mod::test_name* or *test-mod some::mod*, so it is possible to distinguish binaries, single tests, and test modules with this masks: `"^run"`, `"^test "` (the trailing space matters!), and `"^test-mod"` respectively. - -If needed, you can set different values for different platforms: -```jsonc -"rust-analyzer.runnables.extraEnv": [ - { - "platform": "win32", // windows only - "env": { - "APP_DATA": "windows specific data" - } - }, - { - "platform": ["linux"], - "env": { - "APP_DATA": "linux data", - } - }, - { // for all platforms - "env": { - "APP_COMMON_DATA": "xxx", - } - } -] -``` - -==== Compiler feedback from external commands - -Instead of relying on the built-in `cargo check`, you can configure Code to run a command in the background and use the `$rustc-watch` problem matcher to generate inline error markers from its output. - -To do this you need to create a new https://code.visualstudio.com/docs/editor/tasks[VS Code Task] and set `"rust-analyzer.checkOnSave": false` in preferences. - -For example, if you want to run https://crates.io/crates/cargo-watch[`cargo watch`] instead, you might add the following to `.vscode/tasks.json`: - -```json -{ - "label": "Watch", - "group": "build", - "type": "shell", - "command": "cargo watch", - "problemMatcher": "$rustc-watch", - "isBackground": true -} -``` - -==== Live Share - -VS Code Live Share has partial support for rust-analyzer. - -Live Share _requires_ the official Microsoft build of VS Code, OSS builds will not work correctly. - -The host's rust-analyzer instance will be shared with all guests joining the session. -The guests do not have to have the rust-analyzer extension installed for this to work. - -If you are joining a Live Share session and _do_ have rust-analyzer installed locally, commands from the command palette will not work correctly since they will attempt to communicate with the local server.