@@ -2,7 +2,10 @@ use std::borrow::Cow;
2
2
3
3
use syntax:: { AstToken , TextRange , TextSize , ast, ast:: IsString } ;
4
4
5
- use crate :: { AssistContext , AssistId , Assists , utils:: required_hashes} ;
5
+ use crate :: {
6
+ AssistContext , AssistId , Assists ,
7
+ utils:: { required_hashes, string_suffix} ,
8
+ } ;
6
9
7
10
// Assist: make_raw_string
8
11
//
@@ -33,12 +36,15 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
33
36
target,
34
37
|edit| {
35
38
let hashes = "#" . repeat ( required_hashes ( & value) . max ( 1 ) ) ;
39
+ let range = token. syntax ( ) . text_range ( ) ;
40
+ let suffix = string_suffix ( token. text ( ) ) . unwrap_or_default ( ) ;
41
+ let range = TextRange :: new ( range. start ( ) , range. end ( ) - TextSize :: of ( suffix) ) ;
36
42
if matches ! ( value, Cow :: Borrowed ( _) ) {
37
43
// Avoid replacing the whole string to better position the cursor.
38
- edit. insert ( token . syntax ( ) . text_range ( ) . start ( ) , format ! ( "r{hashes}" ) ) ;
39
- edit. insert ( token . syntax ( ) . text_range ( ) . end ( ) , hashes) ;
44
+ edit. insert ( range . start ( ) , format ! ( "r{hashes}" ) ) ;
45
+ edit. insert ( range . end ( ) , hashes) ;
40
46
} else {
41
- edit. replace ( token . syntax ( ) . text_range ( ) , format ! ( "r{hashes}\" {value}\" {hashes}" ) ) ;
47
+ edit. replace ( range , format ! ( "r{hashes}\" {value}\" {hashes}" ) ) ;
42
48
}
43
49
} ,
44
50
)
@@ -73,15 +79,19 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
73
79
|edit| {
74
80
// parse inside string to escape `"`
75
81
let escaped = value. escape_default ( ) . to_string ( ) ;
82
+ let suffix = string_suffix ( token. text ( ) ) . unwrap_or_default ( ) ;
76
83
if let Some ( offsets) = token. quote_offsets ( ) {
77
84
if token. text ( ) [ offsets. contents - token. syntax ( ) . text_range ( ) . start ( ) ] == escaped {
85
+ let end_quote = offsets. quotes . 1 ;
86
+ let end_quote =
87
+ TextRange :: new ( end_quote. start ( ) , end_quote. end ( ) - TextSize :: of ( suffix) ) ;
78
88
edit. replace ( offsets. quotes . 0 , "\" " ) ;
79
- edit. replace ( offsets . quotes . 1 , "\" " ) ;
89
+ edit. replace ( end_quote , "\" " ) ;
80
90
return ;
81
91
}
82
92
}
83
93
84
- edit. replace ( token. syntax ( ) . text_range ( ) , format ! ( "\" {escaped}\" " ) ) ;
94
+ edit. replace ( token. syntax ( ) . text_range ( ) , format ! ( "\" {escaped}\" {suffix} " ) ) ;
85
95
} ,
86
96
)
87
97
}
@@ -109,8 +119,9 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()>
109
119
let text_range = token. syntax ( ) . text_range ( ) ;
110
120
let target = text_range;
111
121
acc. add ( AssistId :: refactor ( "add_hash" ) , "Add #" , target, |edit| {
122
+ let suffix = string_suffix ( token. text ( ) ) . unwrap_or_default ( ) ;
112
123
edit. insert ( text_range. start ( ) + TextSize :: of ( 'r' ) , "#" ) ;
113
- edit. insert ( text_range. end ( ) , "#" ) ;
124
+ edit. insert ( text_range. end ( ) - TextSize :: of ( suffix ) , "#" ) ;
114
125
} )
115
126
}
116
127
@@ -151,8 +162,12 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
151
162
}
152
163
153
164
acc. add ( AssistId :: refactor_rewrite ( "remove_hash" ) , "Remove #" , text_range, |edit| {
165
+ let suffix = string_suffix ( text) . unwrap_or_default ( ) ;
154
166
edit. delete ( TextRange :: at ( text_range. start ( ) + TextSize :: of ( 'r' ) , TextSize :: of ( '#' ) ) ) ;
155
- edit. delete ( TextRange :: new ( text_range. end ( ) - TextSize :: of ( '#' ) , text_range. end ( ) ) ) ;
167
+ edit. delete (
168
+ TextRange :: new ( text_range. end ( ) - TextSize :: of ( '#' ) , text_range. end ( ) )
169
+ - TextSize :: of ( suffix) ,
170
+ ) ;
156
171
} )
157
172
}
158
173
@@ -262,6 +277,23 @@ string"###;
262
277
)
263
278
}
264
279
280
+ #[ test]
281
+ fn make_raw_string_has_suffix ( ) {
282
+ check_assist (
283
+ make_raw_string,
284
+ r#"
285
+ fn f() {
286
+ let s = $0"random string"i32;
287
+ }
288
+ "# ,
289
+ r##"
290
+ fn f() {
291
+ let s = r#"random string"#i32;
292
+ }
293
+ "## ,
294
+ )
295
+ }
296
+
265
297
#[ test]
266
298
fn make_raw_string_not_works_on_partial_string ( ) {
267
299
check_assist_not_applicable (
@@ -316,6 +348,23 @@ string"###;
316
348
)
317
349
}
318
350
351
+ #[ test]
352
+ fn add_hash_has_suffix_works ( ) {
353
+ check_assist (
354
+ add_hash,
355
+ r#"
356
+ fn f() {
357
+ let s = $0r"random string"i32;
358
+ }
359
+ "# ,
360
+ r##"
361
+ fn f() {
362
+ let s = r#"random string"#i32;
363
+ }
364
+ "## ,
365
+ )
366
+ }
367
+
319
368
#[ test]
320
369
fn add_more_hash_works ( ) {
321
370
check_assist (
@@ -333,6 +382,23 @@ string"###;
333
382
)
334
383
}
335
384
385
+ #[ test]
386
+ fn add_more_hash_has_suffix_works ( ) {
387
+ check_assist (
388
+ add_hash,
389
+ r##"
390
+ fn f() {
391
+ let s = $0r#"random"string"#i32;
392
+ }
393
+ "## ,
394
+ r###"
395
+ fn f() {
396
+ let s = r##"random"string"##i32;
397
+ }
398
+ "### ,
399
+ )
400
+ }
401
+
336
402
#[ test]
337
403
fn add_hash_not_works ( ) {
338
404
check_assist_not_applicable (
@@ -367,6 +433,15 @@ string"###;
367
433
)
368
434
}
369
435
436
+ #[ test]
437
+ fn remove_hash_has_suffix_works ( ) {
438
+ check_assist (
439
+ remove_hash,
440
+ r##"fn f() { let s = $0r#"random string"#i32; }"## ,
441
+ r#"fn f() { let s = r"random string"i32; }"# ,
442
+ )
443
+ }
444
+
370
445
#[ test]
371
446
fn cant_remove_required_hash ( ) {
372
447
cov_mark:: check!( cant_remove_required_hash) ;
@@ -397,6 +472,23 @@ string"###;
397
472
)
398
473
}
399
474
475
+ #[ test]
476
+ fn remove_more_hash_has_suffix_works ( ) {
477
+ check_assist (
478
+ remove_hash,
479
+ r###"
480
+ fn f() {
481
+ let s = $0r##"random string"##i32;
482
+ }
483
+ "### ,
484
+ r##"
485
+ fn f() {
486
+ let s = r#"random string"#i32;
487
+ }
488
+ "## ,
489
+ )
490
+ }
491
+
400
492
#[ test]
401
493
fn remove_hash_does_not_work ( ) {
402
494
check_assist_not_applicable ( remove_hash, r#"fn f() { let s = $0"random string"; }"# ) ;
@@ -437,6 +529,23 @@ string"###;
437
529
)
438
530
}
439
531
532
+ #[ test]
533
+ fn make_usual_string_has_suffix_works ( ) {
534
+ check_assist (
535
+ make_usual_string,
536
+ r##"
537
+ fn f() {
538
+ let s = $0r#"random string"#i32;
539
+ }
540
+ "## ,
541
+ r#"
542
+ fn f() {
543
+ let s = "random string"i32;
544
+ }
545
+ "# ,
546
+ )
547
+ }
548
+
440
549
#[ test]
441
550
fn make_usual_string_with_quote_works ( ) {
442
551
check_assist (
@@ -471,6 +580,23 @@ string"###;
471
580
)
472
581
}
473
582
583
+ #[ test]
584
+ fn make_usual_string_more_hash_has_suffix_works ( ) {
585
+ check_assist (
586
+ make_usual_string,
587
+ r###"
588
+ fn f() {
589
+ let s = $0r##"random string"##i32;
590
+ }
591
+ "### ,
592
+ r##"
593
+ fn f() {
594
+ let s = "random string"i32;
595
+ }
596
+ "## ,
597
+ )
598
+ }
599
+
474
600
#[ test]
475
601
fn make_usual_string_not_works ( ) {
476
602
check_assist_not_applicable (
0 commit comments