diff options
-rw-r--r-- | docs/user/README.md | 248 | ||||
-rw-r--r-- | docs/user/features.md | 168 |
2 files changed, 210 insertions, 206 deletions
diff --git a/docs/user/README.md b/docs/user/README.md index ddc6ee048..b25e152d0 100644 --- a/docs/user/README.md +++ b/docs/user/README.md | |||
@@ -1,3 +1,22 @@ | |||
1 | The main interface to rust-analyzer is the | ||
2 | [LSP](https://microsoft.github.io/language-server-protocol/) implementation. To | ||
3 | install lsp server, use `cargo install-lsp`, which is a shorthand for `cargo | ||
4 | install --package ra_lsp_server`. The binary is named `ra_lsp_server`, you | ||
5 | should be able to use it with any LSP-compatible editor. We use custom | ||
6 | extensions to LSP, so special client-side support is required to take full | ||
7 | advantage of rust-analyzer. This repository contains support code for VS Code | ||
8 | and Emacs. | ||
9 | |||
10 | Rust Analyzer needs sources of rust standard library to work, so you might need | ||
11 | to execute | ||
12 | |||
13 | ``` | ||
14 | $ rustup component add rust-src | ||
15 | ``` | ||
16 | |||
17 | See [./features.md] document for a list of features that are available. | ||
18 | |||
19 | ## VS Code | ||
1 | 20 | ||
2 | Prerequisites: | 21 | Prerequisites: |
3 | 22 | ||
@@ -15,227 +34,44 @@ following commands: | |||
15 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 | 34 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 |
16 | $ cd rust-analyzer | 35 | $ cd rust-analyzer |
17 | $ cargo install-code | 36 | $ cargo install-code |
18 | |||
19 | # for stdlib support | ||
20 | $ rustup component add rust-src | ||
21 | ``` | 37 | ``` |
22 | 38 | ||
23 | This will run `cargo install --package ra_lsp_server` to install the server | 39 | This will run `cargo install --package ra_lsp_server` to install the server |
24 | binary into `~/.cargo/bin`, and then will build and install plugin from | 40 | binary into `~/.cargo/bin`, and then will build and install plugin from |
25 | `editors/code`. See | 41 | `editors/code`. See |
26 | [this](https://github.com/rust-analyzer/rust-analyzer/blob/0199572a3d06ff66eeae85a2d2c9762996f0d2d8/crates/tools/src/main.rs#L150) | 42 | [this](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/crates/tools/src/main.rs#L37-L56) |
27 | for details. The installation is expected to *just work*, if it doesn't, report | 43 | for details. The installation is expected to *just work*, if it doesn't, report |
28 | bugs! | 44 | bugs! |
29 | 45 | ||
30 | It's better to remove existing Rust plugins to avoid interference. | 46 | It's better to remove existing Rust plugins to avoid interference. |
31 | 47 | ||
32 | ## Rust Analyzer Specific Features | 48 | Beyond basic LSP features, there are some extension commands which you can |
33 | 49 | invoke via <kbd>Ctrl+Shift+P</kbd> or bind to a shortcut. See [./features.md] | |
34 | These features are implemented as extensions to the language server protocol. | 50 | for details. |
35 | They are more experimental in nature and work only with VS Code. | ||
36 | |||
37 | ### Syntax highlighting | ||
38 | |||
39 | It overrides built-in highlighting, and works only with a specific theme | ||
40 | (zenburn). `rust-analyzer.highlightingOn` setting can be used to disable it. | ||
41 | |||
42 | ### Go to symbol in workspace <kbd>ctrl+t</kbd> | ||
43 | |||
44 | It mostly works on top of the built-in LSP functionality, however `#` and `*` | ||
45 | symbols can be used to narrow down the search. Specifically, | ||
46 | |||
47 | - `#Foo` searches for `Foo` type in the current workspace | ||
48 | - `#foo#` searches for `foo` function in the current workspace | ||
49 | - `#Foo*` searches for `Foo` type among dependencies, excluding `stdlib` | ||
50 | - `#foo#*` searches for `foo` function among dependencies. | ||
51 | |||
52 | That is, `#` switches from "types" to all symbols, `*` switches from the current | ||
53 | workspace to dependencies. | ||
54 | |||
55 | ### Commands <kbd>ctrl+shift+p</kbd> | ||
56 | |||
57 | #### Show Rust Syntax Tree | ||
58 | |||
59 | Shows the parse tree of the current file. It exists mostly for debugging | ||
60 | rust-analyzer itself. | ||
61 | |||
62 | #### Extend Selection | ||
63 | |||
64 | Extends the current selection to the encompassing syntactic construct | ||
65 | (expression, statement, item, module, etc). It works with multiple cursors. Do | ||
66 | bind this command to a key, its super-useful! Expected to be upstreamed to LSP soonish: | ||
67 | https://github.com/Microsoft/language-server-protocol/issues/613 | ||
68 | |||
69 | #### Matching Brace | ||
70 | |||
71 | If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair, | ||
72 | moves cursor to the matching brace. It uses the actual parser to determine | ||
73 | braces, so it won't confuse generics with comparisons. | ||
74 | |||
75 | #### Parent Module | ||
76 | |||
77 | Navigates to the parent module of the current module. | ||
78 | |||
79 | #### Join Lines | ||
80 | |||
81 | Join selected lines into one, smartly fixing up whitespace and trailing commas. | ||
82 | |||
83 | #### Run | ||
84 | |||
85 | Shows popup suggesting to run a test/benchmark/binary **at the current cursor | ||
86 | location**. Super useful for repeatedly running just a single test. Do bind this | ||
87 | to a shortcut! | ||
88 | |||
89 | |||
90 | ### On Typing Assists | ||
91 | |||
92 | Some features trigger on typing certain characters: | ||
93 | |||
94 | - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression. | ||
95 | - Enter inside comments automatically inserts `///` | ||
96 | - typing `.` in a chain method call auto-indents | ||
97 | 51 | ||
52 | ### Settings | ||
98 | 53 | ||
99 | ### Code Actions (Assists) | 54 | * `rust-analyzer.highlightingOn`: enables experimental syntax highlighting |
55 | * `rust-analyzer.showWorkspaceLoadedNotification`: to ease troubleshooting, a | ||
56 | notification is shown by default when a workspace is loaded | ||
57 | * `rust-analyzer.enableEnhancedTyping`: by default, rust-analyzer intercepts | ||
58 | `Enter` key to make it easier to continue comments | ||
59 | * `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable | ||
60 | * `rust-analyzer.enableCargoWatchOnStartup`: prompt to install & enable `cargo | ||
61 | watch` for live error highlighting (note, this **does not** use rust-analyzer) | ||
62 | * `rust-analyzer.trace.server`: enables internal logging | ||
100 | 63 | ||
101 | These are triggered in a particular context via light bulb. We use custom code on | ||
102 | the VS Code side to be able to position cursor. | ||
103 | 64 | ||
65 | ## Emacs | ||
104 | 66 | ||
105 | - Flip `,` | 67 | Prerequisites: |
106 | |||
107 | ```rust | ||
108 | // before: | ||
109 | fn foo(x: usize,<|> dim: (usize, usize)) | ||
110 | // after: | ||
111 | fn foo(dim: (usize, usize), x: usize) | ||
112 | ``` | ||
113 | |||
114 | - Add `#[derive]` | ||
115 | |||
116 | ```rust | ||
117 | // before: | ||
118 | struct Foo { | ||
119 | <|>x: i32 | ||
120 | } | ||
121 | // after: | ||
122 | #[derive(<|>)] | ||
123 | struct Foo { | ||
124 | x: i32 | ||
125 | } | ||
126 | ``` | ||
127 | |||
128 | - Add `impl` | ||
129 | |||
130 | ```rust | ||
131 | // before: | ||
132 | struct Foo<'a, T: Debug> { | ||
133 | <|>t: T | ||
134 | } | ||
135 | // after: | ||
136 | struct Foo<'a, T: Debug> { | ||
137 | t: T | ||
138 | } | ||
139 | |||
140 | impl<'a, T: Debug> Foo<'a, T> { | ||
141 | <|> | ||
142 | } | ||
143 | ``` | ||
144 | |||
145 | - Change visibility | ||
146 | |||
147 | ```rust | ||
148 | // before: | ||
149 | fn<|> foo() {} | ||
150 | |||
151 | // after | ||
152 | pub(crate) fn foo() {} | ||
153 | ``` | ||
154 | |||
155 | - Introduce variable: | ||
156 | |||
157 | ```rust | ||
158 | // before: | ||
159 | fn foo() { | ||
160 | foo(<|>1 + 1<|>); | ||
161 | } | ||
162 | |||
163 | // after: | ||
164 | fn foo() { | ||
165 | let var_name = 1 + 1; | ||
166 | foo(var_name); | ||
167 | } | ||
168 | ``` | ||
169 | |||
170 | - Replace if-let with match: | ||
171 | |||
172 | ```rust | ||
173 | // before: | ||
174 | impl VariantData { | ||
175 | pub fn is_struct(&self) -> bool { | ||
176 | if <|>let VariantData::Struct(..) = *self { | ||
177 | true | ||
178 | } else { | ||
179 | false | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | // after: | ||
185 | impl VariantData { | ||
186 | pub fn is_struct(&self) -> bool { | ||
187 | <|>match *self { | ||
188 | VariantData::Struct(..) => true, | ||
189 | _ => false, | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | ``` | ||
194 | |||
195 | - Split import | ||
196 | |||
197 | ```rust | ||
198 | // before: | ||
199 | use algo:<|>:visitor::{Visitor, visit}; | ||
200 | //after: | ||
201 | use algo::{<|>visitor::{Visitor, visit}}; | ||
202 | ``` | ||
203 | |||
204 | ## LSP features | ||
205 | |||
206 | * **Go to definition**: works correctly for local variables and some paths, | ||
207 | falls back to heuristic name matching for other things for the time being. | ||
208 | |||
209 | * **Completion**: completes paths, including dependencies and standard library. | ||
210 | Does not handle glob imports and macros. Completes fields and inherent | ||
211 | methods. | ||
212 | |||
213 | * **Outline** <kbd>alt+shift+o</kbd> | ||
214 | |||
215 | * **Signature Info** | ||
216 | |||
217 | * **Format document**. Formats the current file with rustfmt. Rustfmt must be | ||
218 | installed separately with `rustup component add rustfmt`. | ||
219 | |||
220 | * **Hover** shows types of expressions and docstings | ||
221 | |||
222 | * **Rename** works for local variables | ||
223 | |||
224 | * **Code Lens** for running tests | ||
225 | |||
226 | * **Folding** | ||
227 | |||
228 | * **Diagnostics** | ||
229 | - missing module for `mod foo;` with a fix to create `foo.rs`. | ||
230 | - struct field shorthand | ||
231 | - unnecessary braces in use item | ||
232 | 68 | ||
69 | `emacs-lsp`, `dash` and `ht` packages. | ||
233 | 70 | ||
234 | ## Performance | 71 | Installation: |
235 | 72 | ||
236 | Rust Analyzer is expected to be pretty fast. Specifically, the initial analysis | 73 | * add |
237 | of the project (i.e, when you first invoke completion or symbols) typically | 74 | [ra-emacs-lsp.el](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/editors/emacs/ra-emacs-lsp.el) |
238 | takes dozen of seconds at most. After that, everything is supposed to be more or | 75 | to load path and require it in `init.el` |
239 | less instant. However currently all analysis results are kept in memory, so | 76 | * run `lsp` in a rust buffer |
240 | memory usage is pretty high. Working with `rust-lang/rust` repo, for example, | 77 | * (Optionally) bind commands like `join-lines` or `extend-selection` to keys |
241 | needs about 5 gigabytes of ram. | ||
diff --git a/docs/user/features.md b/docs/user/features.md new file mode 100644 index 000000000..5df606aee --- /dev/null +++ b/docs/user/features.md | |||
@@ -0,0 +1,168 @@ | |||
1 | This documents is an index of features that rust-analyzer language server provides. | ||
2 | |||
3 | ### Go to symbol in workspace <kbd>ctrl+t</kbd> | ||
4 | |||
5 | It mostly works on top of the built-in LSP functionality, however `#` and `*` | ||
6 | symbols can be used to narrow down the search. Specifically, | ||
7 | |||
8 | - `#Foo` searches for `Foo` type in the current workspace | ||
9 | - `#foo#` searches for `foo` function in the current workspace | ||
10 | - `#Foo*` searches for `Foo` type among dependencies, excluding `stdlib` | ||
11 | - `#foo#*` searches for `foo` function among dependencies. | ||
12 | |||
13 | That is, `#` switches from "types" to all symbols, `*` switches from the current | ||
14 | workspace to dependencies. | ||
15 | |||
16 | ### Commands <kbd>ctrl+shift+p</kbd> | ||
17 | |||
18 | #### Show Rust Syntax Tree | ||
19 | |||
20 | Shows the parse tree of the current file. It exists mostly for debugging | ||
21 | rust-analyzer itself. | ||
22 | |||
23 | #### Extend Selection | ||
24 | |||
25 | Extends the current selection to the encompassing syntactic construct | ||
26 | (expression, statement, item, module, etc). It works with multiple cursors. Do | ||
27 | bind this command to a key, its super-useful! Expected to be upstreamed to LSP soonish: | ||
28 | https://github.com/Microsoft/language-server-protocol/issues/613 | ||
29 | |||
30 | #### Matching Brace | ||
31 | |||
32 | If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair, | ||
33 | moves cursor to the matching brace. It uses the actual parser to determine | ||
34 | braces, so it won't confuse generics with comparisons. | ||
35 | |||
36 | #### Parent Module | ||
37 | |||
38 | Navigates to the parent module of the current module. | ||
39 | |||
40 | #### Join Lines | ||
41 | |||
42 | Join selected lines into one, smartly fixing up whitespace and trailing commas. | ||
43 | |||
44 | #### Run | ||
45 | |||
46 | Shows popup suggesting to run a test/benchmark/binary **at the current cursor | ||
47 | location**. Super useful for repeatedly running just a single test. Do bind this | ||
48 | to a shortcut! | ||
49 | |||
50 | |||
51 | ### On Typing Assists | ||
52 | |||
53 | Some features trigger on typing certain characters: | ||
54 | |||
55 | - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression. | ||
56 | - Enter inside comments automatically inserts `///` | ||
57 | - typing `.` in a chain method call auto-indents | ||
58 | |||
59 | |||
60 | |||
61 | |||
62 | |||
63 | ### Code Actions (Assists) | ||
64 | |||
65 | These are triggered in a particular context via light bulb. We use custom code on | ||
66 | the VS Code side to be able to position cursor. | ||
67 | |||
68 | |||
69 | - Flip `,` | ||
70 | |||
71 | ```rust | ||
72 | // before: | ||
73 | fn foo(x: usize,<|> dim: (usize, usize)) | ||
74 | // after: | ||
75 | fn foo(dim: (usize, usize), x: usize) | ||
76 | ``` | ||
77 | |||
78 | - Add `#[derive]` | ||
79 | |||
80 | ```rust | ||
81 | // before: | ||
82 | struct Foo { | ||
83 | <|>x: i32 | ||
84 | } | ||
85 | // after: | ||
86 | #[derive(<|>)] | ||
87 | struct Foo { | ||
88 | x: i32 | ||
89 | } | ||
90 | ``` | ||
91 | |||
92 | - Add `impl` | ||
93 | |||
94 | ```rust | ||
95 | // before: | ||
96 | struct Foo<'a, T: Debug> { | ||
97 | <|>t: T | ||
98 | } | ||
99 | // after: | ||
100 | struct Foo<'a, T: Debug> { | ||
101 | t: T | ||
102 | } | ||
103 | |||
104 | impl<'a, T: Debug> Foo<'a, T> { | ||
105 | <|> | ||
106 | } | ||
107 | ``` | ||
108 | |||
109 | - Change visibility | ||
110 | |||
111 | ```rust | ||
112 | // before: | ||
113 | fn<|> foo() {} | ||
114 | |||
115 | // after | ||
116 | pub(crate) fn foo() {} | ||
117 | ``` | ||
118 | |||
119 | - Introduce variable: | ||
120 | |||
121 | ```rust | ||
122 | // before: | ||
123 | fn foo() { | ||
124 | foo(<|>1 + 1<|>); | ||
125 | } | ||
126 | |||
127 | // after: | ||
128 | fn foo() { | ||
129 | let var_name = 1 + 1; | ||
130 | foo(var_name); | ||
131 | } | ||
132 | ``` | ||
133 | |||
134 | - Replace if-let with match: | ||
135 | |||
136 | ```rust | ||
137 | // before: | ||
138 | impl VariantData { | ||
139 | pub fn is_struct(&self) -> bool { | ||
140 | if <|>let VariantData::Struct(..) = *self { | ||
141 | true | ||
142 | } else { | ||
143 | false | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // after: | ||
149 | impl VariantData { | ||
150 | pub fn is_struct(&self) -> bool { | ||
151 | <|>match *self { | ||
152 | VariantData::Struct(..) => true, | ||
153 | _ => false, | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | ``` | ||
158 | |||
159 | - Split import | ||
160 | |||
161 | ```rust | ||
162 | // before: | ||
163 | use algo:<|>:visitor::{Visitor, visit}; | ||
164 | //after: | ||
165 | use algo::{<|>visitor::{Visitor, visit}}; | ||
166 | ``` | ||
167 | |||
168 | |||