Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/raw_string.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/raw_string.rs | 152 |
1 files changed, 139 insertions, 13 deletions
diff --git a/crates/ide-assists/src/handlers/raw_string.rs b/crates/ide-assists/src/handlers/raw_string.rs index 5a197f23d0..94b49c5df0 100644 --- a/crates/ide-assists/src/handlers/raw_string.rs +++ b/crates/ide-assists/src/handlers/raw_string.rs @@ -1,8 +1,11 @@ use std::borrow::Cow; -use syntax::{ast, ast::IsString, AstToken, TextRange, TextSize}; +use syntax::{AstToken, TextRange, TextSize, ast, ast::IsString}; -use crate::{utils::required_hashes, AssistContext, AssistId, AssistKind, Assists}; +use crate::{ + AssistContext, AssistId, Assists, + utils::{required_hashes, string_suffix}, +}; // Assist: make_raw_string // @@ -28,17 +31,20 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt let value = token.value().ok()?; let target = token.syntax().text_range(); acc.add( - AssistId("make_raw_string", AssistKind::RefactorRewrite), + AssistId::refactor_rewrite("make_raw_string"), "Rewrite as raw string", target, |edit| { let hashes = "#".repeat(required_hashes(&value).max(1)); + let range = token.syntax().text_range(); + let suffix = string_suffix(token.text()).unwrap_or_default(); + let range = TextRange::new(range.start(), range.end() - TextSize::of(suffix)); if matches!(value, Cow::Borrowed(_)) { // Avoid replacing the whole string to better position the cursor. - edit.insert(token.syntax().text_range().start(), format!("r{hashes}")); - edit.insert(token.syntax().text_range().end(), hashes); + edit.insert(range.start(), format!("r{hashes}")); + edit.insert(range.end(), hashes); } else { - edit.replace(token.syntax().text_range(), format!("r{hashes}\"{value}\"{hashes}")); + edit.replace(range, format!("r{hashes}\"{value}\"{hashes}")); } }, ) @@ -67,21 +73,25 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O let value = token.value().ok()?; let target = token.syntax().text_range(); acc.add( - AssistId("make_usual_string", AssistKind::RefactorRewrite), + AssistId::refactor_rewrite("make_usual_string"), "Rewrite as regular string", target, |edit| { // parse inside string to escape `"` let escaped = value.escape_default().to_string(); + let suffix = string_suffix(token.text()).unwrap_or_default(); if let Some(offsets) = token.quote_offsets() { if token.text()[offsets.contents - token.syntax().text_range().start()] == escaped { + let end_quote = offsets.quotes.1; + let end_quote = + TextRange::new(end_quote.start(), end_quote.end() - TextSize::of(suffix)); edit.replace(offsets.quotes.0, "\""); - edit.replace(offsets.quotes.1, "\""); + edit.replace(end_quote, "\""); return; } } - edit.replace(token.syntax().text_range(), format!("\"{escaped}\"")); + edit.replace(token.syntax().text_range(), format!("\"{escaped}\"{suffix}")); }, ) } @@ -108,9 +118,10 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> } let text_range = token.syntax().text_range(); let target = text_range; - acc.add(AssistId("add_hash", AssistKind::Refactor), "Add #", target, |edit| { + acc.add(AssistId::refactor("add_hash"), "Add #", target, |edit| { + let suffix = string_suffix(token.text()).unwrap_or_default(); edit.insert(text_range.start() + TextSize::of('r'), "#"); - edit.insert(text_range.end(), "#"); + edit.insert(text_range.end() - TextSize::of(suffix), "#"); }) } @@ -150,9 +161,13 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< return None; } - acc.add(AssistId("remove_hash", AssistKind::RefactorRewrite), "Remove #", text_range, |edit| { + acc.add(AssistId::refactor_rewrite("remove_hash"), "Remove #", text_range, |edit| { + let suffix = string_suffix(text).unwrap_or_default(); edit.delete(TextRange::at(text_range.start() + TextSize::of('r'), TextSize::of('#'))); - edit.delete(TextRange::new(text_range.end() - TextSize::of('#'), text_range.end())); + edit.delete( + TextRange::new(text_range.end() - TextSize::of('#'), text_range.end()) + - TextSize::of(suffix), + ); }) } @@ -263,6 +278,23 @@ string"###; } #[test] + fn make_raw_string_has_suffix() { + check_assist( + make_raw_string, + r#" + fn f() { + let s = $0"random string"i32; + } + "#, + r##" + fn f() { + let s = r#"random string"#i32; + } + "##, + ) + } + + #[test] fn make_raw_string_not_works_on_partial_string() { check_assist_not_applicable( make_raw_string, @@ -317,6 +349,23 @@ string"###; } #[test] + fn add_hash_has_suffix_works() { + check_assist( + add_hash, + r#" + fn f() { + let s = $0r"random string"i32; + } + "#, + r##" + fn f() { + let s = r#"random string"#i32; + } + "##, + ) + } + + #[test] fn add_more_hash_works() { check_assist( add_hash, @@ -334,6 +383,23 @@ string"###; } #[test] + fn add_more_hash_has_suffix_works() { + check_assist( + add_hash, + r##" + fn f() { + let s = $0r#"random"string"#i32; + } + "##, + r###" + fn f() { + let s = r##"random"string"##i32; + } + "###, + ) + } + + #[test] fn add_hash_not_works() { check_assist_not_applicable( add_hash, @@ -368,6 +434,15 @@ string"###; } #[test] + fn remove_hash_has_suffix_works() { + check_assist( + remove_hash, + r##"fn f() { let s = $0r#"random string"#i32; }"##, + r#"fn f() { let s = r"random string"i32; }"#, + ) + } + + #[test] fn cant_remove_required_hash() { cov_mark::check!(cant_remove_required_hash); check_assist_not_applicable( @@ -398,6 +473,23 @@ string"###; } #[test] + fn remove_more_hash_has_suffix_works() { + check_assist( + remove_hash, + r###" + fn f() { + let s = $0r##"random string"##i32; + } + "###, + r##" + fn f() { + let s = r#"random string"#i32; + } + "##, + ) + } + + #[test] fn remove_hash_does_not_work() { check_assist_not_applicable(remove_hash, r#"fn f() { let s = $0"random string"; }"#); } @@ -438,6 +530,23 @@ string"###; } #[test] + fn make_usual_string_has_suffix_works() { + check_assist( + make_usual_string, + r##" + fn f() { + let s = $0r#"random string"#i32; + } + "##, + r#" + fn f() { + let s = "random string"i32; + } + "#, + ) + } + + #[test] fn make_usual_string_with_quote_works() { check_assist( make_usual_string, @@ -472,6 +581,23 @@ string"###; } #[test] + fn make_usual_string_more_hash_has_suffix_works() { + check_assist( + make_usual_string, + r###" + fn f() { + let s = $0r##"random string"##i32; + } + "###, + r##" + fn f() { + let s = "random string"i32; + } + "##, + ) + } + + #[test] fn make_usual_string_not_works() { check_assist_not_applicable( make_usual_string, |