diff options
Diffstat (limited to 'docs/user/features.md')
-rw-r--r-- | docs/user/features.md | 424 |
1 files changed, 6 insertions, 418 deletions
diff --git a/docs/user/features.md b/docs/user/features.md index 8b7a8d7fc..c160dd70b 100644 --- a/docs/user/features.md +++ b/docs/user/features.md | |||
@@ -97,424 +97,12 @@ Start `cargo watch` for live error highlighting. Will prompt to install if it's | |||
97 | 97 | ||
98 | Stop `cargo watch` | 98 | Stop `cargo watch` |
99 | 99 | ||
100 | ### Code Actions (Assists) | 100 | ### Assists (Code Actions) |
101 | 101 | ||
102 | These are triggered in a particular context via light bulb. We use custom code on | 102 | Assists, or code actions, are small local refactorings, available in a particular context. |
103 | the VS Code side to be able to position cursor. `<|>` signifies cursor | 103 | They are usually triggered by a shortcut or by clicking a light bulb icon in the editor. |
104 | 104 | ||
105 | - Add `#[derive]` | 105 | See [assists.md](./assists.md) for the list of available assists. |
106 | |||
107 | ```rust | ||
108 | // before: | ||
109 | struct Foo { | ||
110 | <|>x: i32 | ||
111 | } | ||
112 | // after: | ||
113 | #[derive(<|>)] | ||
114 | struct Foo { | ||
115 | x: i32 | ||
116 | } | ||
117 | ``` | ||
118 | |||
119 | - Add `impl` | ||
120 | |||
121 | ```rust | ||
122 | // before: | ||
123 | struct Foo<'a, T: Debug> { | ||
124 | <|>t: T | ||
125 | } | ||
126 | // after: | ||
127 | struct Foo<'a, T: Debug> { | ||
128 | t: T | ||
129 | } | ||
130 | |||
131 | impl<'a, T: Debug> Foo<'a, T> { | ||
132 | <|> | ||
133 | } | ||
134 | ``` | ||
135 | |||
136 | - Add missing `impl` members | ||
137 | |||
138 | ```rust | ||
139 | // before: | ||
140 | trait Foo { | ||
141 | fn foo(&self); | ||
142 | fn bar(&self); | ||
143 | fn baz(&self); | ||
144 | } | ||
145 | |||
146 | struct S; | ||
147 | |||
148 | impl Foo for S { | ||
149 | fn bar(&self) {} | ||
150 | <|> | ||
151 | } | ||
152 | |||
153 | // after: | ||
154 | trait Foo { | ||
155 | fn foo(&self); | ||
156 | fn bar(&self); | ||
157 | fn baz(&self); | ||
158 | } | ||
159 | |||
160 | struct S; | ||
161 | |||
162 | impl Foo for S { | ||
163 | fn bar(&self) {} | ||
164 | fn foo(&self) { unimplemented!() } | ||
165 | fn baz(&self) { unimplemented!() }<|> | ||
166 | } | ||
167 | ``` | ||
168 | |||
169 | - Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) | ||
170 | |||
171 | ```rust | ||
172 | // before: | ||
173 | fn example(x: bool) -> bool { | ||
174 | !x || !x | ||
175 | } | ||
176 | |||
177 | // after: | ||
178 | fn example(x: bool) -> bool { | ||
179 | !(x && x) | ||
180 | } | ||
181 | ``` | ||
182 | |||
183 | - Import path | ||
184 | |||
185 | ```rust | ||
186 | // before: | ||
187 | impl std::fmt::Debug<|> for Foo { | ||
188 | } | ||
189 | |||
190 | // after: | ||
191 | use std::fmt::Debug; | ||
192 | |||
193 | impl Debug<|> for Foo { | ||
194 | } | ||
195 | ``` | ||
196 | |||
197 | - Change Visibility | ||
198 | |||
199 | ```rust | ||
200 | // before: | ||
201 | <|>fn foo() {} | ||
202 | |||
203 | // after: | ||
204 | <|>pub(crate) fn foo() {} | ||
205 | |||
206 | // after: | ||
207 | <|>pub fn foo() {} | ||
208 | ``` | ||
209 | |||
210 | - Fill match arms | ||
211 | |||
212 | ```rust | ||
213 | // before: | ||
214 | enum A { | ||
215 | As, | ||
216 | Bs, | ||
217 | Cs(String), | ||
218 | Ds(String, String), | ||
219 | Es{x: usize, y: usize} | ||
220 | } | ||
221 | |||
222 | fn main() { | ||
223 | let a = A::As; | ||
224 | match a<|> {} | ||
225 | } | ||
226 | |||
227 | // after: | ||
228 | enum A { | ||
229 | As, | ||
230 | Bs, | ||
231 | Cs(String), | ||
232 | Ds(String, String), | ||
233 | Es{x: usize, y: usize} | ||
234 | } | ||
235 | |||
236 | fn main() { | ||
237 | let a = A::As; | ||
238 | match <|>a { | ||
239 | A::As => (), | ||
240 | A::Bs => (), | ||
241 | A::Cs(_) => (), | ||
242 | A::Ds(_, _) => (), | ||
243 | A::Es{x, y} => (), | ||
244 | } | ||
245 | } | ||
246 | ``` | ||
247 | |||
248 | - Fill struct fields | ||
249 | |||
250 | ```rust | ||
251 | // before: | ||
252 | struct S<'a, D> { | ||
253 | a: u32, | ||
254 | b: String, | ||
255 | c: (i32, i32), | ||
256 | d: D, | ||
257 | r: &'a str, | ||
258 | } | ||
259 | |||
260 | fn main() { | ||
261 | let s = S<|> {} | ||
262 | } | ||
263 | |||
264 | // after: | ||
265 | struct S<'a, D> { | ||
266 | a: u32, | ||
267 | b: String, | ||
268 | c: (i32, i32), | ||
269 | d: D, | ||
270 | r: &'a str, | ||
271 | } | ||
272 | |||
273 | fn main() { | ||
274 | let s = <|>S { | ||
275 | a: (), | ||
276 | b: (), | ||
277 | c: (), | ||
278 | d: (), | ||
279 | r: (), | ||
280 | } | ||
281 | } | ||
282 | ``` | ||
283 | |||
284 | - Flip `,` | ||
285 | |||
286 | ```rust | ||
287 | // before: | ||
288 | fn foo(x: usize,<|> dim: (usize, usize)) {} | ||
289 | // after: | ||
290 | fn foo(dim: (usize, usize), x: usize) {} | ||
291 | ``` | ||
292 | |||
293 | - Introduce variable: | ||
294 | |||
295 | ```rust | ||
296 | // before: | ||
297 | fn foo() { | ||
298 | foo(<|>1 + 1<|>); | ||
299 | } | ||
300 | |||
301 | // after: | ||
302 | fn foo() { | ||
303 | let var_name = 1 + 1; | ||
304 | foo(var_name); | ||
305 | } | ||
306 | ``` | ||
307 | |||
308 | - Inline local variable: | ||
309 | |||
310 | ```rust | ||
311 | // before: | ||
312 | fn foo() { | ||
313 | let a<|> = 1 + 1; | ||
314 | let b = a * 10; | ||
315 | } | ||
316 | |||
317 | // after: | ||
318 | fn foo() { | ||
319 | let b = (1 + 1) * 10; | ||
320 | } | ||
321 | ``` | ||
322 | |||
323 | - Remove `dbg!` | ||
324 | |||
325 | ```rust | ||
326 | // before: | ||
327 | fn foo(n: usize) { | ||
328 | if let Some(_) = dbg!(n.<|>checked_sub(4)) { | ||
329 | // ... | ||
330 | } | ||
331 | } | ||
332 | |||
333 | // after: | ||
334 | fn foo(n: usize) { | ||
335 | if let Some(_) = n.<|>checked_sub(4) { | ||
336 | // ... | ||
337 | } | ||
338 | } | ||
339 | ``` | ||
340 | |||
341 | - Replace if-let with match: | ||
342 | |||
343 | ```rust | ||
344 | // before: | ||
345 | impl VariantData { | ||
346 | pub fn is_struct(&self) -> bool { | ||
347 | if <|>let VariantData::Struct(..) = *self { | ||
348 | true | ||
349 | } else { | ||
350 | false | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | |||
355 | // after: | ||
356 | impl VariantData { | ||
357 | pub fn is_struct(&self) -> bool { | ||
358 | <|>match *self { | ||
359 | VariantData::Struct(..) => true, | ||
360 | _ => false, | ||
361 | } | ||
362 | } | ||
363 | } | ||
364 | ``` | ||
365 | |||
366 | - Split import | ||
367 | |||
368 | ```rust | ||
369 | // before: | ||
370 | use crate:<|>:db::{RootDatabase, FileSymbol}; | ||
371 | // after: | ||
372 | use crate::{<|>db::{RootDatabase, FileSymbol}}; | ||
373 | ``` | ||
374 | |||
375 | - Flip binary expression | ||
376 | |||
377 | ```rust | ||
378 | // before: | ||
379 | fn foo() { | ||
380 | if 1 <<|> 2 { | ||
381 | println!("Who would have thought?"); | ||
382 | } | ||
383 | } | ||
384 | // after: | ||
385 | fn foo() { | ||
386 | if 2 ><|> 1 { | ||
387 | println!("Who would have thought?"); | ||
388 | } | ||
389 | } | ||
390 | ``` | ||
391 | |||
392 | - Add explicit type | ||
393 | |||
394 | ```rust | ||
395 | // before: | ||
396 | fn foo() { | ||
397 | let t<|> = (&2, Some(1)); | ||
398 | } | ||
399 | // after: | ||
400 | fn foo() { | ||
401 | let t<|>: (&i32, Option<i32>) = (&2, Some(1)); | ||
402 | } | ||
403 | ``` | ||
404 | |||
405 | - Move guard expression to match arm body | ||
406 | ```rust | ||
407 | // before: | ||
408 | fn f() { | ||
409 | match x { | ||
410 | <|>y @ 4 | y @ 5 if y > 5 => true, | ||
411 | _ => false | ||
412 | } | ||
413 | } | ||
414 | // after: | ||
415 | fn f() { | ||
416 | match x { | ||
417 | y @ 4 | y @ 5 => if y > 5 { <|>true }, | ||
418 | _ => false | ||
419 | } | ||
420 | } | ||
421 | ``` | ||
422 | |||
423 | - Move if condition to match arm guard | ||
424 | ```rust | ||
425 | // before: | ||
426 | fn f() { | ||
427 | let mut t = 'a'; | ||
428 | let chars = "abcd"; | ||
429 | match t { | ||
430 | '\r' => if chars.clone().next().is_some() { | ||
431 | t = 'e';<|> | ||
432 | false | ||
433 | }, | ||
434 | _ => true | ||
435 | } | ||
436 | } | ||
437 | |||
438 | // after: | ||
439 | fn f() { | ||
440 | let mut t = 'a'; | ||
441 | let chars = "abcd"; | ||
442 | match t { | ||
443 | '\r' <|>if chars.clone().next().is_some() => { | ||
444 | t = 'e'; | ||
445 | false | ||
446 | }, | ||
447 | _ => true | ||
448 | } | ||
449 | } | ||
450 | ``` | ||
451 | |||
452 | - Move type bounds to where clause | ||
453 | |||
454 | ```rust | ||
455 | // before: | ||
456 | fn foo<T: u32, F: FnOnce(T) -> T>() {} | ||
457 | |||
458 | // after: | ||
459 | fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {} | ||
460 | ``` | ||
461 | |||
462 | - Make raw string unescaped | ||
463 | |||
464 | ```rust | ||
465 | // before: | ||
466 | fn f() { | ||
467 | let s = <|>"ab\ncd"; | ||
468 | } | ||
469 | |||
470 | // after: | ||
471 | fn f() { | ||
472 | let s = <|>r#"ab | ||
473 | cd"#; | ||
474 | } | ||
475 | ``` | ||
476 | |||
477 | - Make usual string | ||
478 | |||
479 | ```rust | ||
480 | // before: | ||
481 | fn f() { | ||
482 | let s = <|>r#"abcd"#; | ||
483 | } | ||
484 | |||
485 | // after: | ||
486 | fn f() { | ||
487 | let s = <|>"abcd"; | ||
488 | } | ||
489 | ``` | ||
490 | |||
491 | - Add hash | ||
492 | |||
493 | ```rust | ||
494 | // before: | ||
495 | fn f() { | ||
496 | let s = <|>r"abcd"; | ||
497 | } | ||
498 | |||
499 | // after: | ||
500 | fn f() { | ||
501 | let s = <|>r#"abcd"#; | ||
502 | } | ||
503 | ``` | ||
504 | |||
505 | - Remove hash | ||
506 | |||
507 | ```rust | ||
508 | // before: | ||
509 | fn f() { | ||
510 | let s = <|>r#"abcd"#; | ||
511 | } | ||
512 | |||
513 | // after: | ||
514 | fn f() { | ||
515 | let s = <|>r"abcd"; | ||
516 | } | ||
517 | ``` | ||
518 | 106 | ||
519 | ### Magic Completions | 107 | ### Magic Completions |
520 | 108 | ||