Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22768 from j-ricardo-goncalves/master
Issue resolved #22596
| -rw-r--r-- | crates/ide-completion/src/completions/postfix.rs | 12 | ||||
| -rw-r--r-- | crates/ide-completion/src/completions/postfix/format_like.rs | 9 | ||||
| -rw-r--r-- | crates/ide-db/src/source_change.rs | 9 | ||||
| -rw-r--r-- | crates/ide/src/typing/on_enter.rs | 23 |
4 files changed, 36 insertions, 17 deletions
diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 540089cf91..5a3a3ac39c 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -8,6 +8,7 @@ use ide_db::{ RootDatabase, SnippetCap, documentation::{Documentation, HasDocs}, imports::insert_use::ImportScope, + source_change::SnippetEdit, syntax_helpers::suggest_name::NameGenerator, text_edit::TextEdit, ty_filter::TryEnum, @@ -401,7 +402,7 @@ fn get_receiver_text( // The receiver texts should be interpreted as-is, as they are expected to be // normal Rust expressions. - escape_snippet_bits(&mut text); + SnippetEdit::escape_snippet_bits(&mut text); return text; fn indent_of_tail_line(text: &str) -> usize { @@ -411,15 +412,6 @@ fn get_receiver_text( } } -/// Escapes `\` and `$` so that they don't get interpreted as snippet-specific constructs. -/// -/// Note that we don't need to escape the other characters that can be escaped, -/// because they wouldn't be treated as snippet-specific constructs without '$'. -fn escape_snippet_bits(text: &mut String) { - stdx::replace(text, '\\', "\\\\"); - stdx::replace(text, '$', "\\$"); -} - fn receiver_accessor(receiver: &ast::Expr) -> ast::Expr { receiver .syntax() diff --git a/crates/ide-completion/src/completions/postfix/format_like.rs b/crates/ide-completion/src/completions/postfix/format_like.rs index 3b22e8a266..76eddc558b 100644 --- a/crates/ide-completion/src/completions/postfix/format_like.rs +++ b/crates/ide-completion/src/completions/postfix/format_like.rs @@ -18,14 +18,13 @@ use ide_db::{ SnippetCap, + source_change::SnippetEdit, syntax_helpers::format_string_exprs::{Arg, parse_format_exprs, with_placeholders}, }; use syntax::{AstToken, ast}; use crate::{ - Completions, - completions::postfix::{build_postfix_snippet_builder, escape_snippet_bits}, - context::CompletionContext, + Completions, completions::postfix::build_postfix_snippet_builder, context::CompletionContext, }; /// Mapping ("postfix completion item" => "macro to use") @@ -57,10 +56,10 @@ pub(crate) fn add_format_like_completions( if let Ok((mut out, mut exprs)) = parse_format_exprs(receiver_text.text()) { // Escape any snippet bits in the out text and any of the exprs. - escape_snippet_bits(&mut out); + SnippetEdit::escape_snippet_bits(&mut out); for arg in &mut exprs { if let Arg::Ident(text) | Arg::Expr(text) = arg { - escape_snippet_bits(text) + SnippetEdit::escape_snippet_bits(text) } } diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs index 07bf294405..1a3fc0f358 100644 --- a/crates/ide-db/src/source_change.rs +++ b/crates/ide-db/src/source_change.rs @@ -210,6 +210,15 @@ impl SnippetEdit { pub fn into_edit_ranges(self) -> Vec<(u32, TextRange)> { self.0 } + + /// Escapes `\` and `$` so that they don't get interpreted as snippet-specific constructs. + /// + /// Note that we don't need to escape the other characters that can be escaped, + /// because they wouldn't be treated as snippet-specific constructs without '$'. + pub fn escape_snippet_bits(text: &mut String) { + stdx::replace(text, '\\', "\\\\"); + stdx::replace(text, '$', "\\$"); + } } pub struct SourceChangeBuilder { diff --git a/crates/ide/src/typing/on_enter.rs b/crates/ide/src/typing/on_enter.rs index 7d04594a5b..4e3c491418 100644 --- a/crates/ide/src/typing/on_enter.rs +++ b/crates/ide/src/typing/on_enter.rs @@ -1,7 +1,7 @@ //! Handles the `Enter` key press, including comment continuation and //! indentation in brace-delimited constructs. -use ide_db::{FilePosition, RootDatabase}; +use ide_db::{FilePosition, RootDatabase, source_change::SnippetEdit}; use syntax::{ AstNode, SmolStr, SourceFile, SyntaxKind::*, @@ -113,7 +113,8 @@ fn on_enter_in_braces(l_curly: SyntaxToken, position: FilePosition) -> Option<Te return None; } - let (r_curly, content) = brace_contents_on_same_line(&l_curly)?; + let (r_curly, mut content) = brace_contents_on_same_line(&l_curly)?; + SnippetEdit::escape_snippet_bits(&mut content); let indent = IndentLevel::from_token(&l_curly); Some(TextEdit::replace( TextRange::new(position.offset, r_curly.text_range().start()), @@ -683,4 +684,22 @@ use path::{$0 "#, ); } + + #[test] + fn escapes_dollar_sign_in_brace_contents() { + do_check( + r#" +fn f() { + const {$0$bar}; +} +"#, + r#" +fn f() { + const { + $0\$bar + }; +} +"#, + ); + } } |