aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/dev/architecture.md6
-rw-r--r--docs/dev/debugging.md8
-rw-r--r--docs/dev/guide.md8
-rw-r--r--docs/dev/syntax.md44
-rw-r--r--docs/user/assists.md22
-rw-r--r--docs/user/features.md4
-rw-r--r--docs/user/readme.adoc77
7 files changed, 117 insertions, 52 deletions
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md
index 0343b6c81..cee916c09 100644
--- a/docs/dev/architecture.md
+++ b/docs/dev/architecture.md
@@ -46,7 +46,7 @@ can be quickly updated for small modifications.
46 46
47Some of the components of this repository are generated through automatic 47Some of the components of this repository are generated through automatic
48processes. `cargo xtask codegen` runs all generation tasks. Generated code is 48processes. `cargo xtask codegen` runs all generation tasks. Generated code is
49commited to the git repository. 49committed to the git repository.
50 50
51In particular, `cargo xtask codegen` generates: 51In particular, `cargo xtask codegen` generates:
52 52
@@ -56,7 +56,7 @@ In particular, `cargo xtask codegen` generates:
562. [`ast/generated`](https://github.com/rust-analyzer/rust-analyzer/blob/a0be39296d2925972cacd9fbf8b5fb258fad6947/crates/ra_syntax/src/ast/generated.rs) 562. [`ast/generated`](https://github.com/rust-analyzer/rust-analyzer/blob/a0be39296d2925972cacd9fbf8b5fb258fad6947/crates/ra_syntax/src/ast/generated.rs)
57 -- AST data structure. 57 -- AST data structure.
58 58
59.3 [`doc_tests/generated`](https://github.com/rust-analyzer/rust-analyzer/blob/a0be39296d2925972cacd9fbf8b5fb258fad6947/crates/ra_assists/src/doc_tests/generated.rs), 593. [`doc_tests/generated`](https://github.com/rust-analyzer/rust-analyzer/blob/a0be39296d2925972cacd9fbf8b5fb258fad6947/crates/ra_assists/src/doc_tests/generated.rs),
60 [`test_data/parser/inline`](https://github.com/rust-analyzer/rust-analyzer/tree/a0be39296d2925972cacd9fbf8b5fb258fad6947/crates/ra_syntax/test_data/parser/inline) 60 [`test_data/parser/inline`](https://github.com/rust-analyzer/rust-analyzer/tree/a0be39296d2925972cacd9fbf8b5fb258fad6947/crates/ra_syntax/test_data/parser/inline)
61 -- tests for assists and the parser. 61 -- tests for assists and the parser.
62 62
@@ -114,7 +114,7 @@ is responsible for guessing a HIR for a particular source position.
114Underneath, HIR works on top of salsa, using a `HirDatabase` trait. 114Underneath, HIR works on top of salsa, using a `HirDatabase` trait.
115 115
116`ra_hir_xxx` crates have a strong ECS flavor, in that they work with raw ids and 116`ra_hir_xxx` crates have a strong ECS flavor, in that they work with raw ids and
117directly query the databse. 117directly query the database.
118 118
119The top-level `ra_hir` façade crate wraps ids into a more OO-flavored API. 119The top-level `ra_hir` façade crate wraps ids into a more OO-flavored API.
120 120
diff --git a/docs/dev/debugging.md b/docs/dev/debugging.md
index bece6a572..1aa392935 100644
--- a/docs/dev/debugging.md
+++ b/docs/dev/debugging.md
@@ -26,7 +26,7 @@ where **only** the `rust-analyzer` extension being debugged is enabled.
26- `Run Extension (Dev Server)` - runs extension with the locally built LSP server (`target/debug/rust-analyzer`). 26- `Run Extension (Dev Server)` - runs extension with the locally built LSP server (`target/debug/rust-analyzer`).
27 27
28TypeScript debugging is configured to watch your source edits and recompile. 28TypeScript debugging is configured to watch your source edits and recompile.
29To apply changes to an already running debug process press <kbd>Ctrl+Shift+P</kbd> and run the following command in your `[Extension Development Host]` 29To apply changes to an already running debug process, press <kbd>Ctrl+Shift+P</kbd> and run the following command in your `[Extension Development Host]`
30 30
31``` 31```
32> Developer: Reload Window 32> Developer: Reload Window
@@ -76,11 +76,11 @@ Make sure you open a rust file in the `[Extension Development Host]` and try aga
76 76
77Make sure you have run `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`. 77Make sure you have run `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`.
78 78
79By default this should reset back to 1 everytime you log in. 79By default this should reset back to 1 every time you log in.
80 80
81### Breakpoints are never being hit 81### Breakpoints are never being hit
82 82
83Check your version of `lldb` if it's version 6 and lower use the `classic` adapter type. 83Check your version of `lldb`. If it's version 6 and lower, use the `classic` adapter type.
84It's `lldb.adapterType` in settings file. 84It's `lldb.adapterType` in settings file.
85 85
86If you're running `lldb` version 7 change the lldb adapter type to `bundled` or `native`. 86If you're running `lldb` version 7, change the lldb adapter type to `bundled` or `native`.
diff --git a/docs/dev/guide.md b/docs/dev/guide.md
index abbe4c154..c3252f1f6 100644
--- a/docs/dev/guide.md
+++ b/docs/dev/guide.md
@@ -26,7 +26,7 @@ properties hold:
26 26
27## IDE API 27## IDE API
28 28
29To see the bigger picture of how the IDE features works, let's take a look at the [`AnalysisHost`] and 29To see the bigger picture of how the IDE features work, let's take a look at the [`AnalysisHost`] and
30[`Analysis`] pair of types. `AnalysisHost` has three methods: 30[`Analysis`] pair of types. `AnalysisHost` has three methods:
31 31
32* `default()` for creating an empty analysis instance 32* `default()` for creating an empty analysis instance
@@ -131,7 +131,7 @@ mapping between `SourceRoot` IDs (which are assigned by the client) and actual
131analyzer. 131analyzer.
132 132
133Note that `mod`, `#[path]` and `include!()` can only reference files from the 133Note that `mod`, `#[path]` and `include!()` can only reference files from the
134same source root. It is of course is possible to explicitly add extra files to 134same source root. It is of course possible to explicitly add extra files to
135the source root, even `/dev/random`. 135the source root, even `/dev/random`.
136 136
137## Language Server Protocol 137## Language Server Protocol
@@ -192,7 +192,7 @@ task will be canceled as soon as the main loop calls `apply_change` on the
192[`schedule`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L426-L455 192[`schedule`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L426-L455
193[The task]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop/handlers.rs#L205-L223 193[The task]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop/handlers.rs#L205-L223
194 194
195This concludes the overview of the analyzer's programing *interface*. Next, lets 195This concludes the overview of the analyzer's programing *interface*. Next, let's
196dig into the implementation! 196dig into the implementation!
197 197
198## Salsa 198## Salsa
@@ -480,7 +480,7 @@ throughout the analyzer:
480## Source Map pattern 480## Source Map pattern
481 481
482Due to an obscure edge case in completion, IDE needs to know the syntax node of 482Due to an obscure edge case in completion, IDE needs to know the syntax node of
483an use statement which imported the given completion candidate. We can't just 483a use statement which imported the given completion candidate. We can't just
484store the syntax node as a part of name resolution: this will break 484store the syntax node as a part of name resolution: this will break
485incrementality, due to the fact that syntax changes after every file 485incrementality, due to the fact that syntax changes after every file
486modification. 486modification.
diff --git a/docs/dev/syntax.md b/docs/dev/syntax.md
index 4dd1de659..c2864bbbc 100644
--- a/docs/dev/syntax.md
+++ b/docs/dev/syntax.md
@@ -35,7 +35,7 @@ The syntax tree consists of three layers:
35* AST 35* AST
36 36
37Of these, only GreenNodes store the actual data, the other two layers are (non-trivial) views into green tree. 37Of these, only GreenNodes store the actual data, the other two layers are (non-trivial) views into green tree.
38Red-green terminology comes from Roslyn ([link](https://docs.microsoft.com/en-ie/archive/blogs/ericlippert/persistence-facades-and-roslyns-red-green-trees)) and gives the name to the `rowan` library. Green and syntax nodes are defined in rowan, ast is defined in rust-analyzer. 38Red-green terminology comes from Roslyn ([link](https://ericlippert.com/2012/06/08/red-green-trees/)) and gives the name to the `rowan` library. Green and syntax nodes are defined in rowan, ast is defined in rust-analyzer.
39 39
40Syntax trees are a semi-transient data structure. 40Syntax trees are a semi-transient data structure.
41In general, frontend does not keep syntax trees for all files in memory. 41In general, frontend does not keep syntax trees for all files in memory.
@@ -64,7 +64,7 @@ struct Token {
64} 64}
65``` 65```
66 66
67All the difference bettwen the above sketch and the real implementation are strictly due to optimizations. 67All the difference between the above sketch and the real implementation are strictly due to optimizations.
68 68
69Points of note: 69Points of note:
70* The tree is untyped. Each node has a "type tag", `SyntaxKind`. 70* The tree is untyped. Each node has a "type tag", `SyntaxKind`.
@@ -72,7 +72,7 @@ Points of note:
72* Trivia and non-trivia tokens are not distinguished on the type level. 72* Trivia and non-trivia tokens are not distinguished on the type level.
73* Each token carries its full text. 73* Each token carries its full text.
74* The original text can be recovered by concatenating the texts of all tokens in order. 74* The original text can be recovered by concatenating the texts of all tokens in order.
75* Accessing a child of particular type (for example, parameter list of a function) generarly involves linerary traversing the children, looking for a specific `kind`. 75* Accessing a child of particular type (for example, parameter list of a function) generally involves linerary traversing the children, looking for a specific `kind`.
76* Modifying the tree is roughly `O(depth)`. 76* Modifying the tree is roughly `O(depth)`.
77 We don't make special efforts to guarantree that the depth is not liner, but, in practice, syntax trees are branchy and shallow. 77 We don't make special efforts to guarantree that the depth is not liner, but, in practice, syntax trees are branchy and shallow.
78* If mandatory (grammar wise) node is missing from the input, it's just missing from the tree. 78* If mandatory (grammar wise) node is missing from the input, it's just missing from the tree.
@@ -123,7 +123,7 @@ To more compactly store the children, we box *both* interior nodes and tokens, a
123`Either<Arc<Node>, Arc<Token>>` as a single pointer with a tag in the last bit. 123`Either<Arc<Node>, Arc<Token>>` as a single pointer with a tag in the last bit.
124 124
125To avoid allocating EVERY SINGLE TOKEN on the heap, syntax trees use interning. 125To avoid allocating EVERY SINGLE TOKEN on the heap, syntax trees use interning.
126Because the tree is fully imutable, it's valid to structuraly share subtrees. 126Because the tree is fully immutable, it's valid to structurally share subtrees.
127For example, in `1 + 1`, there will be a *single* token for `1` with ref count 2; the same goes for the ` ` whitespace token. 127For example, in `1 + 1`, there will be a *single* token for `1` with ref count 2; the same goes for the ` ` whitespace token.
128Interior nodes are shared as well (for example in `(1 + 1) * (1 + 1)`). 128Interior nodes are shared as well (for example in `(1 + 1) * (1 + 1)`).
129 129
@@ -134,8 +134,8 @@ Currently, the interner is created per-file, but it will be easy to use a per-th
134 134
135We use a `TextSize`, a newtyped `u32`, to store the length of the text. 135We use a `TextSize`, a newtyped `u32`, to store the length of the text.
136 136
137We currently use `SmolStr`, an small object optimized string to store text. 137We currently use `SmolStr`, a small object optimized string to store text.
138This was mostly relevant *before* we implmented tree interning, to avoid allocating common keywords and identifiers. We should switch to storing text data alongside the interned tokens. 138This was mostly relevant *before* we implemented tree interning, to avoid allocating common keywords and identifiers. We should switch to storing text data alongside the interned tokens.
139 139
140#### Alternative designs 140#### Alternative designs
141 141
@@ -162,12 +162,12 @@ Explicit trivia nodes, like in `rowan`, are used by IntelliJ.
162 162
163##### Accessing Children 163##### Accessing Children
164 164
165As noted before, accesing a specific child in the node requires a linear traversal of the children (though we can skip tokens, beacuse the tag is encoded in the pointer itself). 165As noted before, accessing a specific child in the node requires a linear traversal of the children (though we can skip tokens, because the tag is encoded in the pointer itself).
166It is possible to recover O(1) access with another representation. 166It is possible to recover O(1) access with another representation.
167We explicitly store optional and missing (required by the grammar, but not present) nodes. 167We explicitly store optional and missing (required by the grammar, but not present) nodes.
168That is, we use `Option<Node>` for children. 168That is, we use `Option<Node>` for children.
169We also remove trivia tokens from the tree. 169We also remove trivia tokens from the tree.
170This way, each child kind genrerally occupies a fixed position in a parent, and we can use index access to fetch it. 170This way, each child kind generally occupies a fixed position in a parent, and we can use index access to fetch it.
171The cost is that we now need to allocate space for all not-present optional nodes. 171The cost is that we now need to allocate space for all not-present optional nodes.
172So, `fn foo() {}` will have slots for visibility, unsafeness, attributes, abi and return type. 172So, `fn foo() {}` will have slots for visibility, unsafeness, attributes, abi and return type.
173 173
@@ -193,7 +193,7 @@ Modeling this with immutable trees is possible, but annoying.
193### Syntax Nodes 193### Syntax Nodes
194 194
195A function green tree is not super-convenient to use. 195A function green tree is not super-convenient to use.
196The biggest problem is acessing parents (there are no parent pointers!). 196The biggest problem is accessing parents (there are no parent pointers!).
197But there are also "identify" issues. 197But there are also "identify" issues.
198Let's say you want to write a code which builds a list of expressions in a file: `fn collect_exrepssions(file: GreenNode) -> HashSet<GreenNode>`. 198Let's say you want to write a code which builds a list of expressions in a file: `fn collect_exrepssions(file: GreenNode) -> HashSet<GreenNode>`.
199For the input like 199For the input like
@@ -207,7 +207,7 @@ fn main() {
207} 207}
208``` 208```
209 209
210both copies of the `x + 2` expression are representing by equal (and, with interning in mind, actualy the same) green nodes. 210both copies of the `x + 2` expression are representing by equal (and, with interning in mind, actually the same) green nodes.
211Green trees just can't differentiate between the two. 211Green trees just can't differentiate between the two.
212 212
213`SyntaxNode` adds parent pointers and identify semantics to green nodes. 213`SyntaxNode` adds parent pointers and identify semantics to green nodes.
@@ -285,9 +285,9 @@ They also point to the parent (and, consequently, to the root) with an owning `R
285In other words, one needs *one* arc bump when initiating a traversal. 285In other words, one needs *one* arc bump when initiating a traversal.
286 286
287To get rid of allocations, `rowan` takes advantage of `SyntaxNode: !Sync` and uses a thread-local free list of `SyntaxNode`s. 287To get rid of allocations, `rowan` takes advantage of `SyntaxNode: !Sync` and uses a thread-local free list of `SyntaxNode`s.
288In a typical traversal, you only directly hold a few `SyntaxNode`s at a time (and their ancesstors indirectly), so a free list proportional to the depth of the tree removes all allocations in a typical case. 288In a typical traversal, you only directly hold a few `SyntaxNode`s at a time (and their ancestors indirectly), so a free list proportional to the depth of the tree removes all allocations in a typical case.
289 289
290So, while traversal is not exactly incrementing a pointer, it's still prety cheep: tls + rc bump! 290So, while traversal is not exactly incrementing a pointer, it's still pretty cheap: TLS + rc bump!
291 291
292Traversal also yields (cheap) owned nodes, which improves ergonomics quite a bit. 292Traversal also yields (cheap) owned nodes, which improves ergonomics quite a bit.
293 293
@@ -308,15 +308,15 @@ struct SyntaxData {
308} 308}
309``` 309```
310 310
311This allows using true pointer equality for comparision of identities of `SyntaxNodes`. 311This allows using true pointer equality for comparison of identities of `SyntaxNodes`.
312rust-analyzer used to have this design as well, but since we've switch to cursors. 312rust-analyzer used to have this design as well, but we've since switched to cursors.
313The main problem with memoizing the red nodes is that it more than doubles the memory requirenments for fully realized syntax trees. 313The main problem with memoizing the red nodes is that it more than doubles the memory requirements for fully realized syntax trees.
314In contrast, cursors generally retain only a path to the root. 314In contrast, cursors generally retain only a path to the root.
315C# combats increased memory usage by using weak references. 315C# combats increased memory usage by using weak references.
316 316
317### AST 317### AST
318 318
319`GreenTree`s are untyped and homogeneous, because it makes accomodating error nodes, arbitrary whitespace and comments natural, and because it makes possible to write generic tree traversals. 319`GreenTree`s are untyped and homogeneous, because it makes accommodating error nodes, arbitrary whitespace and comments natural, and because it makes possible to write generic tree traversals.
320However, when working with a specific node, like a function definition, one would want a strongly typed API. 320However, when working with a specific node, like a function definition, one would want a strongly typed API.
321 321
322This is what is provided by the AST layer. AST nodes are transparent wrappers over untyped syntax nodes: 322This is what is provided by the AST layer. AST nodes are transparent wrappers over untyped syntax nodes:
@@ -397,7 +397,7 @@ impl HasVisbility for FnDef {
397Points of note: 397Points of note:
398 398
399* Like `SyntaxNode`s, AST nodes are cheap to clone pointer-sized owned values. 399* Like `SyntaxNode`s, AST nodes are cheap to clone pointer-sized owned values.
400* All "fields" are optional, to accomodate incomplete and/or erroneous source code. 400* All "fields" are optional, to accommodate incomplete and/or erroneous source code.
401* It's always possible to go from an ast node to an untyped `SyntaxNode`. 401* It's always possible to go from an ast node to an untyped `SyntaxNode`.
402* It's possible to go in the opposite direction with a checked cast. 402* It's possible to go in the opposite direction with a checked cast.
403* `enum`s allow modeling of arbitrary intersecting subsets of AST types. 403* `enum`s allow modeling of arbitrary intersecting subsets of AST types.
@@ -437,13 +437,13 @@ impl GreenNodeBuilder {
437} 437}
438``` 438```
439 439
440The parser, ultimatelly, needs to invoke the `GreenNodeBuilder`. 440The parser, ultimately, needs to invoke the `GreenNodeBuilder`.
441There are two principal sources of inputs for the parser: 441There are two principal sources of inputs for the parser:
442 * source text, which contains trivia tokens (whitespace and comments) 442 * source text, which contains trivia tokens (whitespace and comments)
443 * token trees from macros, which lack trivia 443 * token trees from macros, which lack trivia
444 444
445Additionaly, input tokens do not correspond 1-to-1 with output tokens. 445Additionally, input tokens do not correspond 1-to-1 with output tokens.
446For example, two consequtive `>` tokens might be glued, by the parser, into a single `>>`. 446For example, two consecutive `>` tokens might be glued, by the parser, into a single `>>`.
447 447
448For these reasons, the parser crate defines a callback interfaces for both input tokens and output trees. 448For these reasons, the parser crate defines a callback interfaces for both input tokens and output trees.
449The explicit glue layer then bridges various gaps. 449The explicit glue layer then bridges various gaps.
@@ -491,7 +491,7 @@ Syntax errors are not stored directly in the tree.
491The primary motivation for this is that syntax tree is not necessary produced by the parser, it may also be assembled manually from pieces (which happens all the time in refactorings). 491The primary motivation for this is that syntax tree is not necessary produced by the parser, it may also be assembled manually from pieces (which happens all the time in refactorings).
492Instead, parser reports errors to an error sink, which stores them in a `Vec`. 492Instead, parser reports errors to an error sink, which stores them in a `Vec`.
493If possible, errors are not reported during parsing and are postponed for a separate validation step. 493If possible, errors are not reported during parsing and are postponed for a separate validation step.
494For example, parser accepts visibility modifiers on trait methods, but then a separate tree traversal flags all such visibilites as erroneous. 494For example, parser accepts visibility modifiers on trait methods, but then a separate tree traversal flags all such visibilities as erroneous.
495 495
496### Macros 496### Macros
497 497
@@ -501,7 +501,7 @@ Specifically, `TreeSink` constructs the tree in lockstep with draining the origi
501In the process, it records which tokens of the tree correspond to which tokens of the input, by using text ranges to identify syntax tokens. 501In the process, it records which tokens of the tree correspond to which tokens of the input, by using text ranges to identify syntax tokens.
502The end result is that parsing an expanded code yields a syntax tree and a mapping of text-ranges of the tree to original tokens. 502The end result is that parsing an expanded code yields a syntax tree and a mapping of text-ranges of the tree to original tokens.
503 503
504To deal with precedence in cases like `$expr * 1`, we use special invisible parenthesis, which are explicitelly handled by the parser 504To deal with precedence in cases like `$expr * 1`, we use special invisible parenthesis, which are explicitly handled by the parser
505 505
506### Whitespace & Comments 506### Whitespace & Comments
507 507
diff --git a/docs/user/assists.md b/docs/user/assists.md
index 6c6943622..ee515949e 100644
--- a/docs/user/assists.md
+++ b/docs/user/assists.md
@@ -175,7 +175,9 @@ trait Trait<T> {
175} 175}
176 176
177impl Trait<u32> for () { 177impl Trait<u32> for () {
178 fn foo(&self) -> u32 { todo!() } 178 fn foo(&self) -> u32 {
179 todo!()
180 }
179 181
180} 182}
181``` 183```
@@ -695,3 +697,21 @@ use std::┃collections::HashMap;
695// AFTER 697// AFTER
696use std::{collections::HashMap}; 698use std::{collections::HashMap};
697``` 699```
700
701## `unwrap_block`
702
703This assist removes if...else, for, while and loop control statements to just keep the body.
704
705```rust
706// BEFORE
707fn foo() {
708 if true {┃
709 println!("foo");
710 }
711}
712
713// AFTER
714fn foo() {
715 println!("foo");
716}
717```
diff --git a/docs/user/features.md b/docs/user/features.md
index 56d2969fd..b9a365fc1 100644
--- a/docs/user/features.md
+++ b/docs/user/features.md
@@ -140,8 +140,8 @@ space or `;` depending on the return type of the function.
140When completing a function call, `()` are automatically inserted. If a function 140When completing a function call, `()` are automatically inserted. If a function
141takes arguments, the cursor is positioned inside the parenthesis. 141takes arguments, the cursor is positioned inside the parenthesis.
142 142
143There are postifx completions, which can be triggerd by typing something like 143There are postfix completions, which can be triggered by typing something like
144`foo().if`. The word after `.` determines postifx completion. Possible variants are: 144`foo().if`. The word after `.` determines postfix completion. Possible variants are:
145 145
146- `expr.if` -> `if expr {}` 146- `expr.if` -> `if expr {}`
147- `expr.match` -> `match expr {}` 147- `expr.match` -> `match expr {}`
diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc
index ce5704836..69f5b13d6 100644
--- a/docs/user/readme.adoc
+++ b/docs/user/readme.adoc
@@ -23,7 +23,7 @@ https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/readme.adoc
23 23
24== Installation 24== Installation
25 25
26In theory, one should be able to just install the server binary and have it automatically work with any editor. 26In theory, one should be able to just install the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>> and have it automatically work with any editor.
27We are not there yet, so some editor specific setup is required. 27We are not there yet, so some editor specific setup is required.
28 28
29Additionally, rust-analyzer needs the sources of the standard library. 29Additionally, rust-analyzer needs the sources of the standard library.
@@ -57,7 +57,11 @@ To disable this notification put the following to `settings.json`
57---- 57----
58==== 58====
59 59
60The server binary is stored in `~/.config/Code/User/globalStorage/matklad.rust-analyzer` (Linux) or in `~/.Library/Application Support/Code/User/globalStorage/matklad.rust-analyzer` (macOS) or in `%APPDATA%\Code\User\globalStorage` (Windows). 60The server binary is stored in:
61
62* Linux: `~/.config/Code/User/globalStorage/matklad.rust-analyzer`
63* macOS: `~/Library/Application Support/Code/User/globalStorage/matklad.rust-analyzer`
64* Windows: `%APPDATA%\Code\User\globalStorage`
61 65
62Note that we only support the latest version of VS Code. 66Note that we only support the latest version of VS Code.
63 67
@@ -108,15 +112,26 @@ Here are some useful self-diagnostic commands:
108* To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Server Trace` in the panel. 112* To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Server Trace` in the panel.
109* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open the `Console` tab of VS Code developer tools. 113* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open the `Console` tab of VS Code developer tools.
110 114
111=== Language Server Binary 115=== rust-analyzer Language Server Binary
112 116
113Other editors generally require the `rust-analyzer` binary to be in `$PATH`. 117Other editors generally require the `rust-analyzer` binary to be in `$PATH`.
114You can download the pre-built binary from the https://github.com/rust-analyzer/rust-analyzer/releases[releases] page. Typically, you then need to rename the binary for your platform, e.g. `rust-analyzer-mac` if you're on Mac OS, to `rust-analzyer` and make it executable in addition to moving it into a directory in your `$PATH`. 118You can download the pre-built binary from the https://github.com/rust-analyzer/rust-analyzer/releases[releases] page. Typically, you then need to rename the binary for your platform, e.g. `rust-analyzer-mac` if you're on Mac OS, to `rust-analyzer` and make it executable in addition to moving it into a directory in your `$PATH`.
119
120On Linux to install the `rust-analyzer` binary into `~/.local/bin`, this commands could be used
121
122[source,bash]
123----
124$ curl -L https://github.com/rust-analyzer/rust-analyzer/releases/latest/download/rust-analyzer-linux -o ~/.local/bin/rust-analyzer
125$ chmod +x ~/.local/bin/rust-analyzer
126----
127
128Ensure `~/.local/bin` is listed in the `$PATH` variable.
115 129
116Alternatively, you can install it from source using the following command: 130Alternatively, you can install it from source using the following command:
117 131
118[source,bash] 132[source,bash]
119---- 133----
134$ git clone https://github.com/rust-analyzer/rust-analyzer.git && cd rust-analyzer
120$ cargo xtask install --server 135$ cargo xtask install --server
121---- 136----
122 137
@@ -139,28 +154,34 @@ $ yay -S rust-analyzer-bin
139 154
140=== Emacs 155=== Emacs
141 156
142Emacs support is maintained https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-rust.el[upstream]. 157Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
158
159Emacs support is maintained as part of the https://github.com/emacs-lsp/lsp-mode[Emacs-LSP] package in https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-rust.el[lsp-rust.el].
143 160
1441. Install the most recent version of `emacs-lsp` package by following the instructions https://github.com/emacs-lsp/lsp-mode[here]. 1611. Install the most recent version of `emacs-lsp` package by following the https://github.com/emacs-lsp/lsp-mode[Emacs-LSP instructions].
1452. Set `lsp-rust-server` to `'rust-analyzer`. 1622. Set `lsp-rust-server` to `'rust-analyzer`.
1463. Run `lsp` in a Rust buffer. 1633. Run `lsp` in a Rust buffer.
1474. (Optionally) bind commands like `lsp-rust-analyzer-join-lines`, `lsp-extend-selection` and `lsp-rust-analyzer-expand-macro` to keys. 1644. (Optionally) bind commands like `lsp-rust-analyzer-join-lines`, `lsp-extend-selection` and `lsp-rust-analyzer-expand-macro` to keys.
148 165
149=== Vim 166=== Vim/NeoVim
150 167
151The are several LSP client implementations for vim: 168Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>. Not needed if the extension can install/update it on its own, coc-rust-analyzer is one example.
169
170The are several LSP client implementations for vim or neovim:
152 171
153==== coc-rust-analyzer 172==== coc-rust-analyzer
154 173
1551. Install coc.nvim by following the instructions at 1741. Install coc.nvim by following the instructions at
156 https://github.com/neoclide/coc.nvim[coc.nvim] 175 https://github.com/neoclide/coc.nvim[coc.nvim]
157 (nodejs required) 176 (Node.js required)
1582. Run `:CocInstall coc-rust-analyzer` to install 1772. Run `:CocInstall coc-rust-analyzer` to install
159 https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer], 178 https://github.com/fannheyward/coc-rust-analyzer[coc-rust-analyzer],
160 this extension implements _most_ of the features supported in the VSCode extension: 179 this extension implements _most_ of the features supported in the VSCode extension:
180 * automatically install and upgrade stable/nightly releases
161 * same configurations as VSCode extension, `rust-analyzer.serverPath`, `rust-analyzer.cargo.features` etc. 181 * same configurations as VSCode extension, `rust-analyzer.serverPath`, `rust-analyzer.cargo.features` etc.
162 * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.ssr` etc. 182 * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.ssr` etc.
163 * highlighting and inlay_hints are not implemented yet 183 * inlay hints for method chaining support, _Neovim Only_
184 * semantic highlighting is not implemented yet
164 185
165==== LanguageClient-neovim 186==== LanguageClient-neovim
166 187
@@ -180,11 +201,11 @@ let g:LanguageClient_serverCommands = {
180==== YouCompleteMe 201==== YouCompleteMe
181 202
1821. Install YouCompleteMe by following the instructions 2031. Install YouCompleteMe by following the instructions
183 https://ycm-core.github.io/YouCompleteMe/#rust-semantic-completion[here] 204 https://github.com/ycm-core/lsp-examples#rust-rust-analyzer[here]
184 205
1852. Configure by adding this to your vim/neovim config file (replacing the existing Rust-specific line if it exists): 2062. Configure by adding this to your vim/neovim config file (replacing the existing Rust-specific line if it exists):
186+ 207+
187[source,vim] 208[source,vim]
188---- 209----
189let g:ycm_language_server = 210let g:ycm_language_server =
190\ [ 211\ [
@@ -197,6 +218,21 @@ let g:ycm_language_server =
197\ ] 218\ ]
198---- 219----
199 220
221==== ALE
222
223To add the LSP server to https://github.com/dense-analysis/ale[ale]:
224
225[source,vim]
226----
227call ale#linter#Define('rust', {
228\ 'name': 'rust-analyzer',
229\ 'lsp': 'stdio',
230\ 'executable': 'rust-analyzer',
231\ 'command': '%e',
232\ 'project_root': '.',
233\})
234----
235
200==== nvim-lsp 236==== nvim-lsp
201 237
202NeoVim 0.5 (not yet released) has built-in language server support. 238NeoVim 0.5 (not yet released) has built-in language server support.
@@ -205,7 +241,7 @@ Once `neovim/nvim-lsp` is installed, use `+lua require'nvim_lsp'.rust_analyzer.s
205 241
206=== Sublime Text 3 242=== Sublime Text 3
207 243
208Prerequisites: You have installed the <<language-server-binary,`rust-analyzer` binary>>. 244Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
209 245
210You also need the `LSP` package. To install it: 246You also need the `LSP` package. To install it:
211 247
@@ -214,11 +250,20 @@ You also need the `LSP` package. To install it:
214 * Type `Install Package Control`, press enter 250 * Type `Install Package Control`, press enter
2152. In the command palette, run `Package control: Install package`, and in the list that pops up, type `LSP` and press enter. 2512. In the command palette, run `Package control: Install package`, and in the list that pops up, type `LSP` and press enter.
216 252
217Finally, with your Rust project open, in the command palette, run `LSP: Enable Language Server In Project` or `LSP: Enable Language Server Globally`, then select `rust-analyzer` in the list that pops up to enable the rust-analyzer LSP. The latter means that rust-analzyer is enabled by default in Rust projects. 253Finally, with your Rust project open, in the command palette, run `LSP: Enable Language Server In Project` or `LSP: Enable Language Server Globally`, then select `rust-analyzer` in the list that pops up to enable the rust-analyzer LSP. The latter means that rust-analyzer is enabled by default in Rust projects.
254
255If it worked, you should see "rust-analyzer, Line X, Column Y" on the left side of the bottom bar, and after waiting a bit, functionality like tooltips on hovering over variables should become available.
256
257If you get an error saying `No such file or directory: 'rust-analyzer'`, see the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>> section on installing the language server binary.
258
259=== Gnome Builder
260
261Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
218 262
219If it worked, you should see "rust-analzyer, Line X, Column Y" on the left side of the bottom bar, and after waiting a bit, functionality like tooltips on hovering over variables should become available. 263Gnome Builder currently has support for RLS, and there's no way to configure the language server executable. A future version might support `rust-analyzer` out of the box.
220 264
221If you get an error saying `No such file or directory: 'rust-analyzer'`, see the <<language-server-binary,section on installing the language server binary>>. 2651. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`).
2662. Enable the Rust Builder plugin.
222 267
223== Usage 268== Usage
224 269