diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt index 7529cebc2ed..01b3e03f05f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt @@ -19,19 +19,26 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.text.StringUtil +import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtStringTemplateExpression +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.startOffset class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention( - KtStringTemplateExpression::class.java, - "To ordinary string literal" + KtStringTemplateExpression::class.java, + "To ordinary string literal" ), LowPriorityAction { override fun isApplicableTo(element: KtStringTemplateExpression): Boolean { return element.text.startsWith("\"\"\"") } override fun applyTo(element: KtStringTemplateExpression, editor: Editor?) { + val startOffset = element.startOffset + val endOffset = element.endOffset + val currentOffset = editor?.caretModel?.currentCaret?.offset ?: startOffset + val text = buildString { append("\"") @@ -42,14 +49,20 @@ class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention text = text.replace("\"", "\\\"") text = StringUtil.convertLineSeparators(text, "\\n") append(text) - } - else { + } else { append(entry.text) } } append("\"") } - element.replace(KtPsiFactory(element).createExpression(text)) + val replaced = element.replaced(KtPsiFactory(element).createExpression(text)) + + val offset = when { + currentOffset - startOffset < 2 -> startOffset + endOffset - currentOffset < 2 -> replaced.endOffset + else -> maxOf(currentOffset - 2, replaced.startOffset) + } + editor?.caretModel?.moveToOffset(offset) } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt index d454dd2e5dd..2bad1d428f5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt @@ -19,14 +19,17 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.text.StringUtilRt +import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.psi.KtEscapeStringTemplateEntry import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtStringTemplateEntry import org.jetbrains.kotlin.psi.KtStringTemplateExpression +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.startOffset class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention( - KtStringTemplateExpression::class.java, - "To raw string literal" + KtStringTemplateExpression::class.java, + "To raw string literal" ), LowPriorityAction { override fun isApplicableTo(element: KtStringTemplateExpression): Boolean { val text = element.text @@ -43,8 +46,19 @@ class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention startOffset + endOffset == currentOffset -> replaced.endOffset + else -> minOf(currentOffset + 2, replaced.endOffset) + } + editor?.caretModel?.moveToOffset(offset) } private fun convertContent(element: KtStringTemplateExpression): String { diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt new file mode 100644 index 00000000000..fdc630b9bfc --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt.after new file mode 100644 index 00000000000..7b44f6ffc36 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt new file mode 100644 index 00000000000..11157cbc09a --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt.after new file mode 100644 index 00000000000..7b44f6ffc36 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt new file mode 100644 index 00000000000..b87c0f7cfc2 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt.after new file mode 100644 index 00000000000..7b44f6ffc36 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt new file mode 100644 index 00000000000..200ee102f8c --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt.after new file mode 100644 index 00000000000..26a96b7e07b --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt new file mode 100644 index 00000000000..3665bcc178a --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt.after new file mode 100644 index 00000000000..3eacf8a90f1 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt new file mode 100644 index 00000000000..54d8f730f43 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt.after new file mode 100644 index 00000000000..7f4471444ac --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt new file mode 100644 index 00000000000..d05403b78ab --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt.after new file mode 100644 index 00000000000..6e53c5c2bee --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt new file mode 100644 index 00000000000..32e963decd3 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt.after new file mode 100644 index 00000000000..6e53c5c2bee --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt b/idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt new file mode 100644 index 00000000000..c287dd0fab1 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt.after new file mode 100644 index 00000000000..6e53c5c2bee --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt.after @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret1.kt b/idea/testData/intentions/toRawStringLiteral/caret1.kt new file mode 100644 index 00000000000..7b44f6ffc36 --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret1.kt @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret1.kt.after b/idea/testData/intentions/toRawStringLiteral/caret1.kt.after new file mode 100644 index 00000000000..fdc630b9bfc --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret1.kt.after @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret2.kt b/idea/testData/intentions/toRawStringLiteral/caret2.kt new file mode 100644 index 00000000000..26a96b7e07b --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret2.kt @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret2.kt.after b/idea/testData/intentions/toRawStringLiteral/caret2.kt.after new file mode 100644 index 00000000000..200ee102f8c --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret2.kt.after @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret3.kt b/idea/testData/intentions/toRawStringLiteral/caret3.kt new file mode 100644 index 00000000000..3eacf8a90f1 --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret3.kt @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret3.kt.after b/idea/testData/intentions/toRawStringLiteral/caret3.kt.after new file mode 100644 index 00000000000..3665bcc178a --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret3.kt.after @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret4.kt b/idea/testData/intentions/toRawStringLiteral/caret4.kt new file mode 100644 index 00000000000..7f4471444ac --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret4.kt @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret4.kt.after b/idea/testData/intentions/toRawStringLiteral/caret4.kt.after new file mode 100644 index 00000000000..54d8f730f43 --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret4.kt.after @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret5.kt b/idea/testData/intentions/toRawStringLiteral/caret5.kt new file mode 100644 index 00000000000..6e53c5c2bee --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret5.kt @@ -0,0 +1 @@ +val s = "foo bar baz" \ No newline at end of file diff --git a/idea/testData/intentions/toRawStringLiteral/caret5.kt.after b/idea/testData/intentions/toRawStringLiteral/caret5.kt.after new file mode 100644 index 00000000000..c287dd0fab1 --- /dev/null +++ b/idea/testData/intentions/toRawStringLiteral/caret5.kt.after @@ -0,0 +1 @@ +val s = """foo bar baz""" \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index ec4f5067f49..df8d4c84dc3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -15471,6 +15471,51 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/toOrdinaryStringLiteral"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } + @TestMetadata("caret1.kt") + public void testCaret1() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret1.kt"); + } + + @TestMetadata("caret2.kt") + public void testCaret2() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret2.kt"); + } + + @TestMetadata("caret3.kt") + public void testCaret3() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret3.kt"); + } + + @TestMetadata("caret4.kt") + public void testCaret4() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret4.kt"); + } + + @TestMetadata("caret5.kt") + public void testCaret5() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret5.kt"); + } + + @TestMetadata("caret6.kt") + public void testCaret6() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret6.kt"); + } + + @TestMetadata("caret7.kt") + public void testCaret7() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret7.kt"); + } + + @TestMetadata("caret8.kt") + public void testCaret8() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret8.kt"); + } + + @TestMetadata("caret9.kt") + public void testCaret9() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/caret9.kt"); + } + @TestMetadata("lineBreakInExpression.kt") public void testLineBreakInExpression() throws Exception { runTest("idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt"); @@ -15509,6 +15554,31 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/toRawStringLiteral/alreadyRaw.kt"); } + @TestMetadata("caret1.kt") + public void testCaret1() throws Exception { + runTest("idea/testData/intentions/toRawStringLiteral/caret1.kt"); + } + + @TestMetadata("caret2.kt") + public void testCaret2() throws Exception { + runTest("idea/testData/intentions/toRawStringLiteral/caret2.kt"); + } + + @TestMetadata("caret3.kt") + public void testCaret3() throws Exception { + runTest("idea/testData/intentions/toRawStringLiteral/caret3.kt"); + } + + @TestMetadata("caret4.kt") + public void testCaret4() throws Exception { + runTest("idea/testData/intentions/toRawStringLiteral/caret4.kt"); + } + + @TestMetadata("caret5.kt") + public void testCaret5() throws Exception { + runTest("idea/testData/intentions/toRawStringLiteral/caret5.kt"); + } + @TestMetadata("dollar.kt") public void testDollar() throws Exception { runTest("idea/testData/intentions/toRawStringLiteral/dollar.kt");