Skip to content

Commit 1d8ed34

Browse files
committed
Escape snippet bits in-between placing snippets
Done so that we don't shift the range that we insert the snippet at.
1 parent 1aeec93 commit 1d8ed34

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

crates/rust-analyzer/src/lsp/to_proto.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1000,23 +1000,35 @@ fn merge_text_and_snippet_edits(
10001000

10011001
let mut new_text = current_indel.insert;
10021002

1003-
// escape out snippet text
1004-
stdx::replace(&mut new_text, '\\', r"\\");
1005-
stdx::replace(&mut new_text, '$', r"\$");
1003+
// find which snippet bits need to be escaped
1004+
let escape_places =
1005+
new_text.rmatch_indices(['\\', '$']).map(|(insert, _)| insert).collect_vec();
1006+
let mut escape_places = escape_places.into_iter().peekable();
1007+
let mut escape_prior_bits = |new_text: &mut String, up_to: usize| {
1008+
for before in escape_places.peeking_take_while(|insert| *insert >= up_to) {
1009+
new_text.insert(before, '\\');
1010+
}
1011+
};
10061012

1007-
// ...and apply!
1013+
// insert snippets, and escaping any needed bits along the way
10081014
for (index, range) in all_snippets.iter().rev() {
1009-
let start = (range.start() - new_range.start()).into();
1010-
let end = (range.end() - new_range.start()).into();
1015+
let text_range = range - new_range.start();
1016+
let (start, end) = (text_range.start().into(), text_range.end().into());
10111017

10121018
if range.is_empty() {
1019+
escape_prior_bits(&mut new_text, start);
10131020
new_text.insert_str(start, &format!("${index}"));
10141021
} else {
1022+
escape_prior_bits(&mut new_text, end);
10151023
new_text.insert(end, '}');
1024+
escape_prior_bits(&mut new_text, start);
10161025
new_text.insert_str(start, &format!("${{{index}:"));
10171026
}
10181027
}
10191028

1029+
// escape any remaining bits
1030+
escape_prior_bits(&mut new_text, 0);
1031+
10201032
edits.push(snippet_text_edit(
10211033
line_index,
10221034
true,

0 commit comments

Comments
 (0)