aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/raw_string.rs740
1 files changed, 370 insertions, 370 deletions
diff --git a/crates/ra_assists/src/raw_string.rs b/crates/ra_assists/src/raw_string.rs
index e00267060..965a64c98 100644
--- a/crates/ra_assists/src/raw_string.rs
+++ b/crates/ra_assists/src/raw_string.rs
@@ -1,370 +1,370 @@
1use hir::db::HirDatabase; 1use hir::db::HirDatabase;
2use ra_syntax::{ast::AstNode, ast::Literal, TextRange, TextUnit}; 2use ra_syntax::{ast::AstNode, ast::Literal, TextRange, TextUnit};
3 3
4use crate::{Assist, AssistCtx, AssistId}; 4use crate::{Assist, AssistCtx, AssistId};
5 5
6pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 6pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
7 let literal = ctx.node_at_offset::<Literal>()?; 7 let literal = ctx.node_at_offset::<Literal>()?;
8 if literal.token().kind() != ra_syntax::SyntaxKind::STRING { 8 if literal.token().kind() != ra_syntax::SyntaxKind::STRING {
9 return None; 9 return None;
10 } 10 }
11 ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| { 11 ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| {
12 edit.target(literal.syntax().text_range()); 12 edit.target(literal.syntax().text_range());
13 edit.insert(literal.syntax().text_range().start(), "r"); 13 edit.insert(literal.syntax().text_range().start(), "r");
14 }); 14 });
15 ctx.build() 15 ctx.build()
16} 16}
17 17
18fn find_usual_string_range(s: &str) -> Option<TextRange> { 18fn find_usual_string_range(s: &str) -> Option<TextRange> {
19 Some(TextRange::from_to( 19 Some(TextRange::from_to(
20 TextUnit::from(s.find('"')? as u32), 20 TextUnit::from(s.find('"')? as u32),
21 TextUnit::from(s.rfind('"')? as u32), 21 TextUnit::from(s.rfind('"')? as u32),
22 )) 22 ))
23} 23}
24 24
25pub(crate) fn make_usual_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 25pub(crate) fn make_usual_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
26 let literal = ctx.node_at_offset::<Literal>()?; 26 let literal = ctx.node_at_offset::<Literal>()?;
27 if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING { 27 if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING {
28 return None; 28 return None;
29 } 29 }
30 let token = literal.token(); 30 let token = literal.token();
31 let text = token.text().as_str(); 31 let text = token.text().as_str();
32 let usual_string_range = find_usual_string_range(text)?; 32 let usual_string_range = find_usual_string_range(text)?;
33 ctx.add_action(AssistId("make_usual_string"), "make usual string", |edit| { 33 ctx.add_action(AssistId("make_usual_string"), "make usual string", |edit| {
34 edit.target(literal.syntax().text_range()); 34 edit.target(literal.syntax().text_range());
35 // parse inside string to escape `"` 35 // parse inside string to escape `"`
36 let start_of_inside = usual_string_range.start().to_usize() + 1; 36 let start_of_inside = usual_string_range.start().to_usize() + 1;
37 let end_of_inside = usual_string_range.end().to_usize(); 37 let end_of_inside = usual_string_range.end().to_usize();
38 let inside_str = &text[start_of_inside..end_of_inside]; 38 let inside_str = &text[start_of_inside..end_of_inside];
39 let escaped = inside_str.escape_default().to_string(); 39 let escaped = inside_str.escape_default().to_string();
40 edit.replace(literal.syntax().text_range(), format!("\"{}\"", escaped)); 40 edit.replace(literal.syntax().text_range(), format!("\"{}\"", escaped));
41 }); 41 });
42 ctx.build() 42 ctx.build()
43} 43}
44 44
45pub(crate) fn add_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 45pub(crate) fn add_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
46 let literal = ctx.node_at_offset::<Literal>()?; 46 let literal = ctx.node_at_offset::<Literal>()?;
47 if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING { 47 if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING {
48 return None; 48 return None;
49 } 49 }
50 ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| { 50 ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| {
51 edit.target(literal.syntax().text_range()); 51 edit.target(literal.syntax().text_range());
52 edit.insert(literal.syntax().text_range().start() + TextUnit::of_char('r'), "#"); 52 edit.insert(literal.syntax().text_range().start() + TextUnit::of_char('r'), "#");
53 edit.insert(literal.syntax().text_range().end(), "#"); 53 edit.insert(literal.syntax().text_range().end(), "#");
54 }); 54 });
55 ctx.build() 55 ctx.build()
56} 56}
57 57
58pub(crate) fn remove_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 58pub(crate) fn remove_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
59 let literal = ctx.node_at_offset::<Literal>()?; 59 let literal = ctx.node_at_offset::<Literal>()?;
60 if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING { 60 if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING {
61 return None; 61 return None;
62 } 62 }
63 let token = literal.token(); 63 let token = literal.token();
64 let text = token.text().as_str(); 64 let text = token.text().as_str();
65 if text.starts_with("r\"") { 65 if text.starts_with("r\"") {
66 // no hash to remove 66 // no hash to remove
67 return None; 67 return None;
68 } 68 }
69 ctx.add_action(AssistId("remove_hash"), "remove hash from raw string", |edit| { 69 ctx.add_action(AssistId("remove_hash"), "remove hash from raw string", |edit| {
70 edit.target(literal.syntax().text_range()); 70 edit.target(literal.syntax().text_range());
71 let result = &text[2..text.len() - 1]; 71 let result = &text[2..text.len() - 1];
72 let result = if result.starts_with("\"") { 72 let result = if result.starts_with("\"") {
73 // no more hash, escape 73 // no more hash, escape
74 let internal_str = &result[1..result.len() - 1]; 74 let internal_str = &result[1..result.len() - 1];
75 format!("\"{}\"", internal_str.escape_default().to_string()) 75 format!("\"{}\"", internal_str.escape_default().to_string())
76 } else { 76 } else {
77 result.to_owned() 77 result.to_owned()
78 }; 78 };
79 edit.replace(literal.syntax().text_range(), format!("r{}", result)); 79 edit.replace(literal.syntax().text_range(), format!("r{}", result));
80 }); 80 });
81 ctx.build() 81 ctx.build()
82} 82}
83 83
84#[cfg(test)] 84#[cfg(test)]
85mod test { 85mod test {
86 use super::*; 86 use super::*;
87 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target}; 87 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target};
88 88
89 #[test] 89 #[test]
90 fn make_raw_string_target() { 90 fn make_raw_string_target() {
91 check_assist_target( 91 check_assist_target(
92 make_raw_string, 92 make_raw_string,
93 r#" 93 r#"
94 fn f() { 94 fn f() {
95 let s = <|>"random string"; 95 let s = <|>"random string";
96 } 96 }
97 "#, 97 "#,
98 r#""random string""#, 98 r#""random string""#,
99 ); 99 );
100 } 100 }
101 101
102 #[test] 102 #[test]
103 fn make_raw_string_works() { 103 fn make_raw_string_works() {
104 check_assist( 104 check_assist(
105 make_raw_string, 105 make_raw_string,
106 r#" 106 r#"
107 fn f() { 107 fn f() {
108 let s = <|>"random string"; 108 let s = <|>"random string";
109 } 109 }
110 "#, 110 "#,
111 r#" 111 r#"
112 fn f() { 112 fn f() {
113 let s = <|>r"random string"; 113 let s = <|>r"random string";
114 } 114 }
115 "#, 115 "#,
116 ) 116 )
117 } 117 }
118 118
119 #[test] 119 #[test]
120 fn make_raw_string_with_escaped_works() { 120 fn make_raw_string_with_escaped_works() {
121 check_assist( 121 check_assist(
122 make_raw_string, 122 make_raw_string,
123 r#" 123 r#"
124 fn f() { 124 fn f() {
125 let s = <|>"random\nstring"; 125 let s = <|>"random\nstring";
126 } 126 }
127 "#, 127 "#,
128 r#" 128 r#"
129 fn f() { 129 fn f() {
130 let s = <|>r"random\nstring"; 130 let s = <|>r"random\nstring";
131 } 131 }
132 "#, 132 "#,
133 ) 133 )
134 } 134 }
135 135
136 #[test] 136 #[test]
137 fn make_raw_string_not_works() { 137 fn make_raw_string_not_works() {
138 check_assist_not_applicable( 138 check_assist_not_applicable(
139 make_raw_string, 139 make_raw_string,
140 r#" 140 r#"
141 fn f() { 141 fn f() {
142 let s = <|>r"random string"; 142 let s = <|>r"random string";
143 } 143 }
144 "#, 144 "#,
145 ); 145 );
146 } 146 }
147 147
148 #[test] 148 #[test]
149 fn add_hash_target() { 149 fn add_hash_target() {
150 check_assist_target( 150 check_assist_target(
151 add_hash, 151 add_hash,
152 r#" 152 r#"
153 fn f() { 153 fn f() {
154 let s = <|>r"random string"; 154 let s = <|>r"random string";
155 } 155 }
156 "#, 156 "#,
157 r#"r"random string""#, 157 r#"r"random string""#,
158 ); 158 );
159 } 159 }
160 160
161 #[test] 161 #[test]
162 fn add_hash_works() { 162 fn add_hash_works() {
163 check_assist( 163 check_assist(
164 add_hash, 164 add_hash,
165 r#" 165 r#"
166 fn f() { 166 fn f() {
167 let s = <|>r"random string"; 167 let s = <|>r"random string";
168 } 168 }
169 "#, 169 "#,
170 r##" 170 r##"
171 fn f() { 171 fn f() {
172 let s = <|>r#"random string"#; 172 let s = <|>r#"random string"#;
173 } 173 }
174 "##, 174 "##,
175 ) 175 )
176 } 176 }
177 177
178 #[test] 178 #[test]
179 fn add_more_hash_works() { 179 fn add_more_hash_works() {
180 check_assist( 180 check_assist(
181 add_hash, 181 add_hash,
182 r##" 182 r##"
183 fn f() { 183 fn f() {
184 let s = <|>r#"random"string"#; 184 let s = <|>r#"random"string"#;
185 } 185 }
186 "##, 186 "##,
187 r###" 187 r###"
188 fn f() { 188 fn f() {
189 let s = <|>r##"random"string"##; 189 let s = <|>r##"random"string"##;
190 } 190 }
191 "###, 191 "###,
192 ) 192 )
193 } 193 }
194 194
195 #[test] 195 #[test]
196 fn add_hash_not_works() { 196 fn add_hash_not_works() {
197 check_assist_not_applicable( 197 check_assist_not_applicable(
198 add_hash, 198 add_hash,
199 r#" 199 r#"
200 fn f() { 200 fn f() {
201 let s = <|>"random string"; 201 let s = <|>"random string";
202 } 202 }
203 "#, 203 "#,
204 ); 204 );
205 } 205 }
206 206
207 #[test] 207 #[test]
208 fn remove_hash_target() { 208 fn remove_hash_target() {
209 check_assist_target( 209 check_assist_target(
210 remove_hash, 210 remove_hash,
211 r##" 211 r##"
212 fn f() { 212 fn f() {
213 let s = <|>r#"random string"#; 213 let s = <|>r#"random string"#;
214 } 214 }
215 "##, 215 "##,
216 r##"r#"random string"#"##, 216 r##"r#"random string"#"##,
217 ); 217 );
218 } 218 }
219 219
220 #[test] 220 #[test]
221 fn remove_hash_works() { 221 fn remove_hash_works() {
222 check_assist( 222 check_assist(
223 remove_hash, 223 remove_hash,
224 r##" 224 r##"
225 fn f() { 225 fn f() {
226 let s = <|>r#"random string"#; 226 let s = <|>r#"random string"#;
227 } 227 }
228 "##, 228 "##,
229 r#" 229 r#"
230 fn f() { 230 fn f() {
231 let s = <|>r"random string"; 231 let s = <|>r"random string";
232 } 232 }
233 "#, 233 "#,
234 ) 234 )
235 } 235 }
236 236
237 #[test] 237 #[test]
238 fn remove_hash_with_quote_works() { 238 fn remove_hash_with_quote_works() {
239 check_assist( 239 check_assist(
240 remove_hash, 240 remove_hash,
241 r##" 241 r##"
242 fn f() { 242 fn f() {
243 let s = <|>r#"random"str"ing"#; 243 let s = <|>r#"random"str"ing"#;
244 } 244 }
245 "##, 245 "##,
246 r#" 246 r#"
247 fn f() { 247 fn f() {
248 let s = <|>r"random\"str\"ing"; 248 let s = <|>r"random\"str\"ing";
249 } 249 }
250 "#, 250 "#,
251 ) 251 )
252 } 252 }
253 253
254 #[test] 254 #[test]
255 fn remove_more_hash_works() { 255 fn remove_more_hash_works() {
256 check_assist( 256 check_assist(
257 remove_hash, 257 remove_hash,
258 r###" 258 r###"
259 fn f() { 259 fn f() {
260 let s = <|>r##"random string"##; 260 let s = <|>r##"random string"##;
261 } 261 }
262 "###, 262 "###,
263 r##" 263 r##"
264 fn f() { 264 fn f() {
265 let s = <|>r#"random string"#; 265 let s = <|>r#"random string"#;
266 } 266 }
267 "##, 267 "##,
268 ) 268 )
269 } 269 }
270 270
271 #[test] 271 #[test]
272 fn remove_hash_not_works() { 272 fn remove_hash_not_works() {
273 check_assist_not_applicable( 273 check_assist_not_applicable(
274 remove_hash, 274 remove_hash,
275 r#" 275 r#"
276 fn f() { 276 fn f() {
277 let s = <|>"random string"; 277 let s = <|>"random string";
278 } 278 }
279 "#, 279 "#,
280 ); 280 );
281 } 281 }
282 282
283 #[test] 283 #[test]
284 fn remove_hash_no_hash_not_works() { 284 fn remove_hash_no_hash_not_works() {
285 check_assist_not_applicable( 285 check_assist_not_applicable(
286 remove_hash, 286 remove_hash,
287 r#" 287 r#"
288 fn f() { 288 fn f() {
289 let s = <|>r"random string"; 289 let s = <|>r"random string";
290 } 290 }
291 "#, 291 "#,
292 ); 292 );
293 } 293 }
294 294
295 #[test] 295 #[test]
296 fn make_usual_string_target() { 296 fn make_usual_string_target() {
297 check_assist_target( 297 check_assist_target(
298 make_usual_string, 298 make_usual_string,
299 r##" 299 r##"
300 fn f() { 300 fn f() {
301 let s = <|>r#"random string"#; 301 let s = <|>r#"random string"#;
302 } 302 }
303 "##, 303 "##,
304 r##"r#"random string"#"##, 304 r##"r#"random string"#"##,
305 ); 305 );
306 } 306 }
307 307
308 #[test] 308 #[test]
309 fn make_usual_string_works() { 309 fn make_usual_string_works() {
310 check_assist( 310 check_assist(
311 make_usual_string, 311 make_usual_string,
312 r##" 312 r##"
313 fn f() { 313 fn f() {
314 let s = <|>r#"random string"#; 314 let s = <|>r#"random string"#;
315 } 315 }
316 "##, 316 "##,
317 r#" 317 r#"
318 fn f() { 318 fn f() {
319 let s = <|>"random string"; 319 let s = <|>"random string";
320 } 320 }
321 "#, 321 "#,
322 ) 322 )
323 } 323 }
324 324
325 #[test] 325 #[test]
326 fn make_usual_string_with_quote_works() { 326 fn make_usual_string_with_quote_works() {
327 check_assist( 327 check_assist(
328 make_usual_string, 328 make_usual_string,
329 r##" 329 r##"
330 fn f() { 330 fn f() {
331 let s = <|>r#"random"str"ing"#; 331 let s = <|>r#"random"str"ing"#;
332 } 332 }
333 "##, 333 "##,
334 r#" 334 r#"
335 fn f() { 335 fn f() {
336 let s = <|>"random\"str\"ing"; 336 let s = <|>"random\"str\"ing";
337 } 337 }
338 "#, 338 "#,
339 ) 339 )
340 } 340 }
341 341
342 #[test] 342 #[test]
343 fn make_usual_string_more_hash_works() { 343 fn make_usual_string_more_hash_works() {
344 check_assist( 344 check_assist(
345 make_usual_string, 345 make_usual_string,
346 r###" 346 r###"
347 fn f() { 347 fn f() {
348 let s = <|>r##"random string"##; 348 let s = <|>r##"random string"##;
349 } 349 }
350 "###, 350 "###,
351 r##" 351 r##"
352 fn f() { 352 fn f() {
353 let s = <|>"random string"; 353 let s = <|>"random string";
354 } 354 }
355 "##, 355 "##,
356 ) 356 )
357 } 357 }
358 358
359 #[test] 359 #[test]
360 fn make_usual_string_not_works() { 360 fn make_usual_string_not_works() {
361 check_assist_not_applicable( 361 check_assist_not_applicable(
362 make_usual_string, 362 make_usual_string,
363 r#" 363 r#"
364 fn f() { 364 fn f() {
365 let s = <|>"random string"; 365 let s = <|>"random string";
366 } 366 }
367 "#, 367 "#,
368 ); 368 );
369 } 369 }
370} 370}