Skip to content

Commit cf96735

Browse files
author
Geobert Quach
committed
feat(assists): Apply comments
1 parent 18d30c8 commit cf96735

File tree

1 file changed

+59
-100
lines changed

1 file changed

+59
-100
lines changed

crates/ra_assists/src/raw_string.rs

Lines changed: 59 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,84 @@
11
use hir::db::HirDatabase;
2-
use ra_syntax::{ast::AstNode, ast::Literal, SyntaxText, TextRange, TextUnit};
2+
use ra_syntax::{ast::AstNode, ast::Literal, TextRange, TextUnit};
33

4-
use crate::{assist_ctx::AssistBuilder, Assist, AssistCtx, AssistId};
4+
use crate::{Assist, AssistCtx, AssistId};
55

66
pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
77
let literal = ctx.node_at_offset::<Literal>()?;
8-
if literal.token().kind() == ra_syntax::SyntaxKind::STRING {
9-
ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| {
10-
edit.target(literal.syntax().text_range());
11-
edit.insert(literal.syntax().text_range().start(), "r");
12-
});
13-
ctx.build()
14-
} else {
15-
None
8+
if literal.token().kind() != ra_syntax::SyntaxKind::STRING {
9+
return None;
1610
}
11+
ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| {
12+
edit.target(literal.syntax().text_range());
13+
edit.insert(literal.syntax().text_range().start(), "r");
14+
});
15+
ctx.build()
16+
}
17+
18+
fn find_usual_string_range(s: &str) -> Option<TextRange> {
19+
Some(TextRange::from_to(
20+
TextUnit::from(s.find('"')? as u32),
21+
TextUnit::from(s.rfind('"')? as u32),
22+
))
1723
}
1824

1925
pub(crate) fn make_usual_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
2026
let literal = ctx.node_at_offset::<Literal>()?;
21-
if literal.token().kind() == ra_syntax::SyntaxKind::RAW_STRING {
22-
ctx.add_action(AssistId("make_usual_string"), "make usual string", |edit| {
23-
let text = literal.syntax().text();
24-
let usual_start_pos = text.find_char('"').unwrap(); // we have a RAW_STRING
25-
let end = literal.syntax().text_range().end();
26-
let mut i = 0;
27-
let mut pos = 0;
28-
let mut c = text.char_at(end - TextUnit::from(i));
29-
while c != Some('"') {
30-
if c != None {
31-
pos += 1;
32-
}
33-
i += 1;
34-
c = text.char_at(end - TextUnit::from(i));
35-
}
36-
37-
edit.target(literal.syntax().text_range());
38-
edit.delete(TextRange::from_to(
39-
literal.syntax().text_range().start(),
40-
literal.syntax().text_range().start() + usual_start_pos,
41-
));
42-
edit.delete(TextRange::from_to(
43-
literal.syntax().text_range().end() - TextUnit::from(pos),
44-
literal.syntax().text_range().end(),
45-
));
46-
// parse inside string to escape `"`
47-
let start_of_inside = usual_start_pos + TextUnit::from(1);
48-
let end_of_inside = text.len() - usual_start_pos - TextUnit::from(1);
49-
let inside_str = text.slice(TextRange::from_to(start_of_inside, end_of_inside));
50-
escape_double_quote(
51-
edit,
52-
&inside_str,
53-
literal.syntax().text_range().start() + start_of_inside,
54-
);
55-
});
56-
ctx.build()
57-
} else {
58-
None
27+
if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING {
28+
return None;
5929
}
30+
let token = literal.token();
31+
let text = token.text().as_str();
32+
let usual_string_range = find_usual_string_range(text)?;
33+
ctx.add_action(AssistId("make_usual_string"), "make usual string", |edit| {
34+
edit.target(literal.syntax().text_range());
35+
// parse inside string to escape `"`
36+
let start_of_inside = usual_string_range.start().to_usize() + 1;
37+
let end_of_inside = usual_string_range.end().to_usize();
38+
let inside_str = &text[start_of_inside..end_of_inside];
39+
let escaped = inside_str.escape_default().to_string();
40+
edit.replace(literal.syntax().text_range(), format!("\"{}\"", escaped));
41+
});
42+
ctx.build()
6043
}
6144

6245
pub(crate) fn add_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
6346
let literal = ctx.node_at_offset::<Literal>()?;
64-
if literal.token().kind() == ra_syntax::SyntaxKind::RAW_STRING {
65-
ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| {
66-
edit.target(literal.syntax().text_range());
67-
edit.insert(literal.syntax().text_range().start() + TextUnit::from(1), "#");
68-
edit.insert(literal.syntax().text_range().end(), "#");
69-
});
70-
ctx.build()
71-
} else {
72-
None
47+
if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING {
48+
return None;
7349
}
74-
}
75-
76-
fn escape_double_quote(edit: &mut AssistBuilder, inside_str: &SyntaxText, offset: TextUnit) {
77-
let mut start = TextUnit::from(0);
78-
inside_str.for_each_chunk(|chunk| {
79-
let end = start + TextUnit::of_str(chunk);
80-
let mut i = 0;
81-
for c in chunk.to_string().chars() {
82-
if c == '"' {
83-
edit.insert(offset + start + TextUnit::from(i), "\\");
84-
}
85-
i += 1;
86-
}
87-
start = end;
50+
ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| {
51+
edit.target(literal.syntax().text_range());
52+
edit.insert(literal.syntax().text_range().start() + TextUnit::of_char('r'), "#");
53+
edit.insert(literal.syntax().text_range().end(), "#");
8854
});
55+
ctx.build()
8956
}
9057

9158
pub(crate) fn remove_hash(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
9259
let literal = ctx.node_at_offset::<Literal>()?;
93-
if literal.token().kind() == ra_syntax::SyntaxKind::RAW_STRING {
94-
if !literal.syntax().text().contains_char('#') {
95-
return None;
96-
}
97-
ctx.add_action(AssistId("remove_hash"), "remove hash from raw string", |edit| {
98-
edit.target(literal.syntax().text_range());
99-
edit.delete(TextRange::from_to(
100-
literal.syntax().text_range().start() + TextUnit::from(1),
101-
literal.syntax().text_range().start() + TextUnit::from(2),
102-
));
103-
edit.delete(TextRange::from_to(
104-
literal.syntax().text_range().end() - TextUnit::from(1),
105-
literal.syntax().text_range().end(),
106-
));
107-
let text = literal.syntax().text();
108-
if text.char_at(TextUnit::from(2)) == Some('"') {
109-
// no more hash after assist, need to escape any `"` in the string
110-
let inside_str = text
111-
.slice(TextRange::from_to(TextUnit::from(3), text.len() - TextUnit::from(2)));
112-
escape_double_quote(
113-
edit,
114-
&inside_str,
115-
literal.syntax().text_range().start() + TextUnit::from(3),
116-
);
117-
}
118-
});
119-
ctx.build()
120-
} else {
121-
None
60+
if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING {
61+
return None;
62+
}
63+
let token = literal.token();
64+
let text = token.text().as_str();
65+
if text.starts_with("r\"") {
66+
// no hash to remove
67+
return None;
12268
}
69+
ctx.add_action(AssistId("remove_hash"), "remove hash from raw string", |edit| {
70+
edit.target(literal.syntax().text_range());
71+
let result = &text[2..text.len() - 1];
72+
let result = if result.starts_with("\"") {
73+
// no more hash, escape
74+
let internal_str = &result[1..result.len() - 1];
75+
format!("\"{}\"", internal_str.escape_default().to_string())
76+
} else {
77+
result.to_owned()
78+
};
79+
edit.replace(literal.syntax().text_range(), format!("r{}", result));
80+
});
81+
ctx.build()
12382
}
12483

12584
#[cfg(test)]

0 commit comments

Comments
 (0)