diff options
| author | DropDemBits <r3usrlnd@gmail.com> | 2024-02-16 00:14:39 -0500 |
|---|---|---|
| committer | DropDemBits <r3usrlnd@gmail.com> | 2024-02-16 00:28:02 -0500 |
| commit | 1d8ed3408e16a8fa9fc591b94ce3295d3a10ca41 (patch) | |
| tree | 33617585d8b40e8be91d9f18a895b753df5ea9c6 | |
| parent | 1aeec93412d4e06fed78d72ae824be9d107187e8 (diff) | |
| download | rust-1d8ed3408e16a8fa9fc591b94ce3295d3a10ca41.tar.gz rust-1d8ed3408e16a8fa9fc591b94ce3295d3a10ca41.zip | |
Escape snippet bits in-between placing snippets
Done so that we don't shift the range that we insert the snippet at.
| -rw-r--r-- | crates/rust-analyzer/src/lsp/to_proto.rs | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index 3d3bb8e83da..6d4bae5206b 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1000,23 +1000,35 @@ fn merge_text_and_snippet_edits( let mut new_text = current_indel.insert; - // escape out snippet text - stdx::replace(&mut new_text, '\\', r"\\"); - stdx::replace(&mut new_text, '$', r"\$"); + // find which snippet bits need to be escaped + let escape_places = + new_text.rmatch_indices(['\\', '$']).map(|(insert, _)| insert).collect_vec(); + let mut escape_places = escape_places.into_iter().peekable(); + let mut escape_prior_bits = |new_text: &mut String, up_to: usize| { + for before in escape_places.peeking_take_while(|insert| *insert >= up_to) { + new_text.insert(before, '\\'); + } + }; - // ...and apply! + // insert snippets, and escaping any needed bits along the way for (index, range) in all_snippets.iter().rev() { - let start = (range.start() - new_range.start()).into(); - let end = (range.end() - new_range.start()).into(); + let text_range = range - new_range.start(); + let (start, end) = (text_range.start().into(), text_range.end().into()); if range.is_empty() { + escape_prior_bits(&mut new_text, start); new_text.insert_str(start, &format!("${index}")); } else { + escape_prior_bits(&mut new_text, end); new_text.insert(end, '}'); + escape_prior_bits(&mut new_text, start); new_text.insert_str(start, &format!("${{{index}:")); } } + // escape any remaining bits + escape_prior_bits(&mut new_text, 0); + edits.push(snippet_text_edit( line_index, true, |
