diff options
author | Geobert Quach <[email protected]> | 2019-09-26 20:31:45 +0100 |
---|---|---|
committer | Geobert Quach <[email protected]> | 2019-09-26 20:31:45 +0100 |
commit | 281e1071558dff3138805de49dfbb0ad91b3acd3 (patch) | |
tree | 55c2bca96fdf15f53c067dcc3b70b84e967006c4 /crates/ra_assists/src/assists | |
parent | 53a30d9e69ee5149e4fdb1c6fe4081281e879d0e (diff) |
feat(assists): Make raw string unescaped
Diffstat (limited to 'crates/ra_assists/src/assists')
-rw-r--r-- | crates/ra_assists/src/assists/raw_string.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/crates/ra_assists/src/assists/raw_string.rs b/crates/ra_assists/src/assists/raw_string.rs index 965a64c98..fe396806b 100644 --- a/crates/ra_assists/src/assists/raw_string.rs +++ b/crates/ra_assists/src/assists/raw_string.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use hir::db::HirDatabase; | 1 | use hir::db::HirDatabase; |
2 | use ra_syntax::{ast::AstNode, ast::Literal, TextRange, TextUnit}; | 2 | use ra_syntax::{ast::AstNode, ast::Literal, TextRange, TextUnit}; |
3 | use rustc_lexer; | ||
3 | 4 | ||
4 | use crate::{Assist, AssistCtx, AssistId}; | 5 | use crate::{Assist, AssistCtx, AssistId}; |
5 | 6 | ||
@@ -15,6 +16,39 @@ pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As | |||
15 | ctx.build() | 16 | ctx.build() |
16 | } | 17 | } |
17 | 18 | ||
19 | pub(crate) fn make_raw_string_unescaped(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | ||
20 | let literal = ctx.node_at_offset::<Literal>()?; | ||
21 | if literal.token().kind() != ra_syntax::SyntaxKind::STRING { | ||
22 | return None; | ||
23 | } | ||
24 | let token = literal.token(); | ||
25 | let text = token.text().as_str(); | ||
26 | if !text.contains(&['\\', '\r'][..]) { | ||
27 | return None; | ||
28 | } | ||
29 | let usual_string_range = find_usual_string_range(text)?; | ||
30 | ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| { | ||
31 | edit.target(literal.syntax().text_range()); | ||
32 | let start_of_inside = usual_string_range.start().to_usize() + 1; | ||
33 | let end_of_inside = usual_string_range.end().to_usize(); | ||
34 | let inside_str = &text[start_of_inside..end_of_inside]; | ||
35 | let mut unescaped = String::with_capacity(inside_str.len()); | ||
36 | let mut error = Ok(()); | ||
37 | rustc_lexer::unescape::unescape_str(inside_str, &mut |_, unescaped_char| { | ||
38 | match unescaped_char { | ||
39 | Ok(c) => unescaped.push(c), | ||
40 | Err(_) => error = Err(()), | ||
41 | } | ||
42 | }); | ||
43 | if error.is_err() { | ||
44 | eprintln!("Error unescaping string"); | ||
45 | } else { | ||
46 | edit.replace(literal.syntax().text_range(), format!("r\"{}\"", unescaped)); | ||
47 | } | ||
48 | }); | ||
49 | ctx.build() | ||
50 | } | ||
51 | |||
18 | fn find_usual_string_range(s: &str) -> Option<TextRange> { | 52 | fn find_usual_string_range(s: &str) -> Option<TextRange> { |
19 | Some(TextRange::from_to( | 53 | Some(TextRange::from_to( |
20 | TextUnit::from(s.find('"')? as u32), | 54 | TextUnit::from(s.find('"')? as u32), |
@@ -146,6 +180,49 @@ mod test { | |||
146 | } | 180 | } |
147 | 181 | ||
148 | #[test] | 182 | #[test] |
183 | fn make_raw_string_unescaped_target() { | ||
184 | check_assist_target( | ||
185 | make_raw_string_unescaped, | ||
186 | r#" | ||
187 | fn f() { | ||
188 | let s = <|>"random\nstring"; | ||
189 | } | ||
190 | "#, | ||
191 | r#""random\nstring""#, | ||
192 | ); | ||
193 | } | ||
194 | |||
195 | #[test] | ||
196 | fn make_raw_string_unescaped_works() { | ||
197 | check_assist( | ||
198 | make_raw_string_unescaped, | ||
199 | r#" | ||
200 | fn f() { | ||
201 | let s = <|>"random\nstring"; | ||
202 | } | ||
203 | "#, | ||
204 | r#" | ||
205 | fn f() { | ||
206 | let s = <|>r"random | ||
207 | string"; | ||
208 | } | ||
209 | "#, | ||
210 | ) | ||
211 | } | ||
212 | |||
213 | #[test] | ||
214 | fn make_raw_string_unescaped_dont_works() { | ||
215 | check_assist_not_applicable( | ||
216 | make_raw_string_unescaped, | ||
217 | r#" | ||
218 | fn f() { | ||
219 | let s = <|>"random string"; | ||
220 | } | ||
221 | "#, | ||
222 | ) | ||
223 | } | ||
224 | |||
225 | #[test] | ||
149 | fn add_hash_target() { | 226 | fn add_hash_target() { |
150 | check_assist_target( | 227 | check_assist_target( |
151 | add_hash, | 228 | add_hash, |