aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assists/raw_string.rs62
-rw-r--r--crates/ra_assists/src/assists/remove_dbg.rs20
-rw-r--r--crates/ra_assists/src/assists/replace_if_let_with_match.rs28
-rw-r--r--crates/ra_assists/src/assists/split_import.rs13
-rw-r--r--crates/ra_assists/src/doc_tests/generated.rs126
-rw-r--r--docs/user/assists.md119
-rw-r--r--docs/user/features.md174
7 files changed, 359 insertions, 183 deletions
diff --git a/crates/ra_assists/src/assists/raw_string.rs b/crates/ra_assists/src/assists/raw_string.rs
index ea756d1ca..2df48a838 100644
--- a/crates/ra_assists/src/assists/raw_string.rs
+++ b/crates/ra_assists/src/assists/raw_string.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use hir::db::HirDatabase; 1use hir::db::HirDatabase;
4use ra_syntax::{ 2use ra_syntax::{
5 SyntaxKind::{RAW_STRING, STRING}, 3 SyntaxKind::{RAW_STRING, STRING},
@@ -9,6 +7,21 @@ use rustc_lexer;
9 7
10use crate::{Assist, AssistCtx, AssistId}; 8use crate::{Assist, AssistCtx, AssistId};
11 9
10// Assist: make_raw_string
11//
12// Adds `r#` to a plain string literal.
13//
14// ```
15// fn main() {
16// "Hello,<|> World!";
17// }
18// ```
19// ->
20// ```
21// fn main() {
22// r#"Hello, World!"#;
23// }
24// ```
12pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 25pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
13 let token = ctx.find_token_at_offset(STRING)?; 26 let token = ctx.find_token_at_offset(STRING)?;
14 let text = token.text().as_str(); 27 let text = token.text().as_str();
@@ -40,6 +53,21 @@ pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As
40 ctx.build() 53 ctx.build()
41} 54}
42 55
56// Assist: make_usual_string
57//
58// Turns a raw string into a plain string.
59//
60// ```
61// fn main() {
62// r#"Hello,<|> "World!""#;
63// }
64// ```
65// ->
66// ```
67// fn main() {
68// "Hello, \"World!\"";
69// }
70// ```
43pub(crate) fn make_usual_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 71pub(crate) fn make_usual_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
44 let token = ctx.find_token_at_offset(RAW_STRING)?; 72 let token = ctx.find_token_at_offset(RAW_STRING)?;
45 let text = token.text().as_str(); 73 let text = token.text().as_str();
@@ -56,6 +84,21 @@ pub(crate) fn make_usual_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<
56 ctx.build() 84 ctx.build()
57} 85}
58 86
87// Assist: add_hash
88//
89// Adds a hash to a raw string literal.
90//
91// ```
92// fn main() {
93// r#"Hello,<|> World!"#;
94// }
95// ```
96// ->
97// ```
98// fn main() {
99// r##"Hello, World!"##;
100// }
101// ```
59pub(crate) fn add_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 102pub(crate) fn add_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
60 let token = ctx.find_token_at_offset(RAW_STRING)?; 103 let token = ctx.find_token_at_offset(RAW_STRING)?;
61 ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| { 104 ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| {
@@ -66,6 +109,21 @@ pub(crate) fn add_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
66 ctx.build() 109 ctx.build()
67} 110}
68 111
112// Assist: remove_hash
113//
114// Removes a hash from a raw string literal.
115//
116// ```
117// fn main() {
118// r#"Hello,<|> World!"#;
119// }
120// ```
121// ->
122// ```
123// fn main() {
124// r"Hello, World!";
125// }
126// ```
69pub(crate) fn remove_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 127pub(crate) fn remove_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
70 let token = ctx.find_token_at_offset(RAW_STRING)?; 128 let token = ctx.find_token_at_offset(RAW_STRING)?;
71 let text = token.text().as_str(); 129 let text = token.text().as_str();
diff --git a/crates/ra_assists/src/assists/remove_dbg.rs b/crates/ra_assists/src/assists/remove_dbg.rs
index ac2c43e1a..44b8de814 100644
--- a/crates/ra_assists/src/assists/remove_dbg.rs
+++ b/crates/ra_assists/src/assists/remove_dbg.rs
@@ -1,12 +1,26 @@
1//! FIXME: write short doc here
2
3use crate::{Assist, AssistCtx, AssistId};
4use hir::db::HirDatabase; 1use hir::db::HirDatabase;
5use ra_syntax::{ 2use ra_syntax::{
6 ast::{self, AstNode}, 3 ast::{self, AstNode},
7 TextUnit, T, 4 TextUnit, T,
8}; 5};
9 6
7use crate::{Assist, AssistCtx, AssistId};
8
9// Assist: remove_dbg
10//
11// Removes `dbg!()` macro call.
12//
13// ```
14// fn main() {
15// <|>dbg!(92);
16// }
17// ```
18// ->
19// ```
20// fn main() {
21// 92;
22// }
23// ```
10pub(crate) fn remove_dbg(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 24pub(crate) fn remove_dbg(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
11 let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?; 25 let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
12 26
diff --git a/crates/ra_assists/src/assists/replace_if_let_with_match.rs b/crates/ra_assists/src/assists/replace_if_let_with_match.rs
index da276e47b..58ef2ff20 100644
--- a/crates/ra_assists/src/assists/replace_if_let_with_match.rs
+++ b/crates/ra_assists/src/assists/replace_if_let_with_match.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use format_buf::format; 1use format_buf::format;
4use hir::db::HirDatabase; 2use hir::db::HirDatabase;
5use ra_fmt::extract_trivial_expression; 3use ra_fmt::extract_trivial_expression;
@@ -7,6 +5,32 @@ use ra_syntax::{ast, AstNode};
7 5
8use crate::{Assist, AssistCtx, AssistId}; 6use crate::{Assist, AssistCtx, AssistId};
9 7
8// Assist: replace_if_let_with_match
9//
10// Replaces `if let` with an else branch with a `match` expression.
11//
12// ```
13// enum Action { Move { distance: u32 }, Stop }
14//
15// fn handle(action: Action) {
16// <|>if let Action::Move { distance } = action {
17// foo(distance)
18// } else {
19// bar()
20// }
21// }
22// ```
23// ->
24// ```
25// enum Action { Move { distance: u32 }, Stop }
26//
27// fn handle(action: Action) {
28// match action {
29// Action::Move { distance } => foo(distance),
30// _ => bar(),
31// }
32// }
33// ```
10pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 34pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
11 let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; 35 let if_expr: ast::IfExpr = ctx.find_node_at_offset()?;
12 let cond = if_expr.condition()?; 36 let cond = if_expr.condition()?;
diff --git a/crates/ra_assists/src/assists/split_import.rs b/crates/ra_assists/src/assists/split_import.rs
index 09bde1b72..8d8a28987 100644
--- a/crates/ra_assists/src/assists/split_import.rs
+++ b/crates/ra_assists/src/assists/split_import.rs
@@ -1,5 +1,3 @@
1//! FIXME: write short doc here
2
3use std::iter::successors; 1use std::iter::successors;
4 2
5use hir::db::HirDatabase; 3use hir::db::HirDatabase;
@@ -7,6 +5,17 @@ use ra_syntax::{ast, AstNode, TextUnit, T};
7 5
8use crate::{Assist, AssistCtx, AssistId}; 6use crate::{Assist, AssistCtx, AssistId};
9 7
8// Assist: split_import
9//
10// Wraps the tail of import into braces.
11//
12// ```
13// use std::<|>collections::HashMap;
14// ```
15// ->
16// ```
17// use std::{collections::HashMap};
18// ```
10pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 19pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
11 let colon_colon = ctx.find_token_at_offset(T![::])?; 20 let colon_colon = ctx.find_token_at_offset(T![::])?;
12 let path = ast::Path::cast(colon_colon.parent())?; 21 let path = ast::Path::cast(colon_colon.parent())?;
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs
index 09677af68..b8d335911 100644
--- a/crates/ra_assists/src/doc_tests/generated.rs
+++ b/crates/ra_assists/src/doc_tests/generated.rs
@@ -40,6 +40,23 @@ fn main() {
40} 40}
41 41
42#[test] 42#[test]
43fn doctest_add_hash() {
44 check(
45 "add_hash",
46 r#####"
47fn main() {
48 r#"Hello,<|> World!"#;
49}
50"#####,
51 r#####"
52fn main() {
53 r##"Hello, World!"##;
54}
55"#####,
56 )
57}
58
59#[test]
43fn doctest_add_impl() { 60fn doctest_add_impl() {
44 check( 61 check(
45 "add_impl", 62 "add_impl",
@@ -275,6 +292,40 @@ fn main() {
275} 292}
276 293
277#[test] 294#[test]
295fn doctest_make_raw_string() {
296 check(
297 "make_raw_string",
298 r#####"
299fn main() {
300 "Hello,<|> World!";
301}
302"#####,
303 r#####"
304fn main() {
305 r#"Hello, World!"#;
306}
307"#####,
308 )
309}
310
311#[test]
312fn doctest_make_usual_string() {
313 check(
314 "make_usual_string",
315 r#####"
316fn main() {
317 r#"Hello,<|> "World!""#;
318}
319"#####,
320 r#####"
321fn main() {
322 "Hello, \"World!\"";
323}
324"#####,
325 )
326}
327
328#[test]
278fn doctest_merge_match_arms() { 329fn doctest_merge_match_arms() {
279 check( 330 check(
280 "merge_match_arms", 331 "merge_match_arms",
@@ -370,3 +421,78 @@ fn handle(action: Action) {
370"#####, 421"#####,
371 ) 422 )
372} 423}
424
425#[test]
426fn doctest_remove_dbg() {
427 check(
428 "remove_dbg",
429 r#####"
430fn main() {
431 <|>dbg!(92);
432}
433"#####,
434 r#####"
435fn main() {
436 92;
437}
438"#####,
439 )
440}
441
442#[test]
443fn doctest_remove_hash() {
444 check(
445 "remove_hash",
446 r#####"
447fn main() {
448 r#"Hello,<|> World!"#;
449}
450"#####,
451 r#####"
452fn main() {
453 r"Hello, World!";
454}
455"#####,
456 )
457}
458
459#[test]
460fn doctest_replace_if_let_with_match() {
461 check(
462 "replace_if_let_with_match",
463 r#####"
464enum Action { Move { distance: u32 }, Stop }
465
466fn handle(action: Action) {
467 <|>if let Action::Move { distance } = action {
468 foo(distance)
469 } else {
470 bar()
471 }
472}
473"#####,
474 r#####"
475enum Action { Move { distance: u32 }, Stop }
476
477fn handle(action: Action) {
478 match action {
479 Action::Move { distance } => foo(distance),
480 _ => bar(),
481 }
482}
483"#####,
484 )
485}
486
487#[test]
488fn doctest_split_import() {
489 check(
490 "split_import",
491 r#####"
492use std::<|>collections::HashMap;
493"#####,
494 r#####"
495use std::{collections::HashMap};
496"#####,
497 )
498}
diff --git a/docs/user/assists.md b/docs/user/assists.md
index 34a95696c..e4d08a7dc 100644
--- a/docs/user/assists.md
+++ b/docs/user/assists.md
@@ -38,6 +38,22 @@ fn main() {
38} 38}
39``` 39```
40 40
41## `add_hash`
42
43Adds a hash to a raw string literal.
44
45```rust
46// BEFORE
47fn main() {
48 r#"Hello,┃ World!"#;
49}
50
51// AFTER
52fn main() {
53 r##"Hello, World!"##;
54}
55```
56
41## `add_impl` 57## `add_impl`
42 58
43Adds a new inherent impl for a type. 59Adds a new inherent impl for a type.
@@ -266,6 +282,38 @@ fn main() {
266} 282}
267``` 283```
268 284
285## `make_raw_string`
286
287Adds `r#` to a plain string literal.
288
289```rust
290// BEFORE
291fn main() {
292 "Hello,┃ World!";
293}
294
295// AFTER
296fn main() {
297 r#"Hello, World!"#;
298}
299```
300
301## `make_usual_string`
302
303Turns a raw string into a plain string.
304
305```rust
306// BEFORE
307fn main() {
308 r#"Hello,┃ "World!""#;
309}
310
311// AFTER
312fn main() {
313 "Hello, \"World!\"";
314}
315```
316
269## `merge_match_arms` 317## `merge_match_arms`
270 318
271Merges identical match arms. 319Merges identical match arms.
@@ -358,3 +406,74 @@ fn handle(action: Action) {
358 } 406 }
359} 407}
360``` 408```
409
410## `remove_dbg`
411
412Removes `dbg!()` macro call.
413
414```rust
415// BEFORE
416fn main() {
417 ┃dbg!(92);
418}
419
420// AFTER
421fn main() {
422 92;
423}
424```
425
426## `remove_hash`
427
428Removes a hash from a raw string literal.
429
430```rust
431// BEFORE
432fn main() {
433 r#"Hello,┃ World!"#;
434}
435
436// AFTER
437fn main() {
438 r"Hello, World!";
439}
440```
441
442## `replace_if_let_with_match`
443
444Replaces `if let` with an else branch with a `match` expression.
445
446```rust
447// BEFORE
448enum Action { Move { distance: u32 }, Stop }
449
450fn handle(action: Action) {
451 ┃if let Action::Move { distance } = action {
452 foo(distance)
453 } else {
454 bar()
455 }
456}
457
458// AFTER
459enum Action { Move { distance: u32 }, Stop }
460
461fn handle(action: Action) {
462 match action {
463 Action::Move { distance } => foo(distance),
464 _ => bar(),
465 }
466}
467```
468
469## `split_import`
470
471Wraps the tail of import into braces.
472
473```rust
474// BEFORE
475use std::┃collections::HashMap;
476
477// AFTER
478use std::{collections::HashMap};
479```
diff --git a/docs/user/features.md b/docs/user/features.md
index 2e213e34c..7ae2ca7b6 100644
--- a/docs/user/features.md
+++ b/docs/user/features.md
@@ -118,180 +118,6 @@ impl Debug<|> for Foo {
118} 118}
119``` 119```
120 120
121- Fill struct fields
122
123```rust
124// before:
125struct S<'a, D> {
126 a: u32,
127 b: String,
128 c: (i32, i32),
129 d: D,
130 r: &'a str,
131}
132
133fn main() {
134 let s = S<|> {}
135}
136
137// after:
138struct S<'a, D> {
139 a: u32,
140 b: String,
141 c: (i32, i32),
142 d: D,
143 r: &'a str,
144}
145
146fn main() {
147 let s = <|>S {
148 a: (),
149 b: (),
150 c: (),
151 d: (),
152 r: (),
153 }
154}
155```
156
157- Remove `dbg!`
158
159```rust
160// before:
161fn foo(n: usize) {
162 if let Some(_) = dbg!(n.<|>checked_sub(4)) {
163 // ...
164 }
165}
166
167// after:
168fn foo(n: usize) {
169 if let Some(_) = n.<|>checked_sub(4) {
170 // ...
171 }
172}
173```
174
175- Replace if-let with match:
176
177```rust
178// before:
179impl VariantData {
180 pub fn is_struct(&self) -> bool {
181 if <|>let VariantData::Struct(..) = *self {
182 true
183 } else {
184 false
185 }
186 }
187}
188
189// after:
190impl VariantData {
191 pub fn is_struct(&self) -> bool {
192 <|>match *self {
193 VariantData::Struct(..) => true,
194 _ => false,
195 }
196 }
197}
198```
199
200- Split import
201
202```rust
203// before:
204use crate:<|>:db::{RootDatabase, FileSymbol};
205// after:
206use crate::{<|>db::{RootDatabase, FileSymbol}};
207```
208
209- Move if condition to match arm guard
210```rust
211// before:
212fn f() {
213 let mut t = 'a';
214 let chars = "abcd";
215 match t {
216 '\r' => if chars.clone().next().is_some() {
217 t = 'e';<|>
218 false
219 },
220 _ => true
221 }
222}
223
224// after:
225fn f() {
226 let mut t = 'a';
227 let chars = "abcd";
228 match t {
229 '\r' <|>if chars.clone().next().is_some() => {
230 t = 'e';
231 false
232 },
233 _ => true
234 }
235}
236```
237
238- Make raw string unescaped
239
240```rust
241// before:
242fn f() {
243 let s = <|>"ab\ncd";
244}
245
246// after:
247fn f() {
248 let s = <|>r#"ab
249cd"#;
250}
251```
252
253- Make usual string
254
255```rust
256// before:
257fn f() {
258 let s = <|>r#"abcd"#;
259}
260
261// after:
262fn f() {
263 let s = <|>"abcd";
264}
265```
266
267- Add hash
268
269```rust
270// before:
271fn f() {
272 let s = <|>r"abcd";
273}
274
275// after:
276fn f() {
277 let s = <|>r#"abcd"#;
278}
279```
280
281- Remove hash
282
283```rust
284// before:
285fn f() {
286 let s = <|>r#"abcd"#;
287}
288
289// after:
290fn f() {
291 let s = <|>r"abcd";
292}
293```
294
295### Magic Completions 121### Magic Completions
296 122
297In addition to usual reference completion, rust-analyzer provides some ✨magic✨ 123In addition to usual reference completion, rust-analyzer provides some ✨magic✨