java text blocks: escape quotes on paste (IDEA-217353)

to be continued

GitOrigin-RevId: aa6cf21a39ef5ea37da794c0eeee368a9456de16
This commit is contained in:
Anna Kozlova
2019-07-02 10:59:54 +02:00
committed by intellij-monorepo-bot
parent 8cb91e1346
commit 6487b64bfb
4 changed files with 51 additions and 1 deletions

View File

@@ -136,6 +136,9 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
else if (isCharLiteral(token)) {
return escapeCharCharacters(text, token);
}
else if (isTextBlock(token)) {
return escapeTextBlock(text);
}
return text;
}
@@ -177,7 +180,7 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
if (elementAtSelectionStart == null) {
return null;
}
if (!isStringLiteral(elementAtSelectionStart) && !isCharLiteral(elementAtSelectionStart)) {
if (!isStringLiteral(elementAtSelectionStart) && !isCharLiteral(elementAtSelectionStart) && !isTextBlock(elementAtSelectionStart)) {
return null;
}
@@ -208,6 +211,11 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
ASTNode node = token.getNode();
return node != null && node.getElementType() == JavaTokenType.STRING_LITERAL;
}
protected boolean isTextBlock(@NotNull PsiElement token) {
ASTNode node = token.getNode();
return node != null && node.getElementType() == JavaTokenType.TEXT_BLOCK_LITERAL;
}
@Nullable
protected TextRange getEscapedRange(@NotNull PsiElement token) {
@@ -215,6 +223,10 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
TextRange tokenRange = token.getTextRange();
return new TextRange(tokenRange.getStartOffset() + 1, tokenRange.getEndOffset() - 1); // Excluding String/char literal quotes
}
else if (isTextBlock(token) && token.getTextLength() >= 7) {
TextRange tokenRange = token.getTextRange();
return new TextRange(tokenRange.getStartOffset() + 4, tokenRange.getEndOffset() - 3);
}
else {
return null;
}
@@ -226,4 +238,19 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
StringUtil.escapeStringCharacters(s.length(), s, isStringLiteral(token) ? "\"" : "\'", buffer);
return buffer.toString();
}
@NotNull
protected String escapeTextBlock(@NotNull String text) {
StringBuilder buffer = new StringBuilder(text.length());
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
//todo don't escape single quote; prefer \""" if the next char is not a quote
StringUtil.escapeStringCharacters(line.length(), line, buffer);
if (i < lines.length - 1) {
buffer.append("\n");
}
}
return buffer.toString();
}
}

View File

@@ -0,0 +1,5 @@
class C {
String empty = """
\"\"\"
target\"\"\"<caret>""";
}

View File

@@ -0,0 +1,4 @@
class C {
String empty = """
<caret>""";
}

View File

@@ -2,6 +2,7 @@
package com.intellij.java.codeInsight.daemon
import com.intellij.JavaTestUtil
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
class JavaTextBlocksHighlightingTest : LightJavaCodeInsightFixtureTestCase() {
@@ -20,4 +21,17 @@ class JavaTextBlocksHighlightingTest : LightJavaCodeInsightFixtureTestCase() {
myFixture.configureByFile("${getTestName(false)}.java")
myFixture.checkHighlighting()
}
fun testEscapeQuotes() {
doTestPaste("\"\"\"\ntarget\"\"\"".trimIndent())
}
private fun doTestPaste(textToPaste: String) {
myFixture.configureByText("plain.txt", "<selection>$textToPaste</selection>")
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_COPY)
myFixture.configureByFile("${getTestName(false)}.java")
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PASTE)
myFixture.checkResultByFile("${getTestName(false)}.after.java")
}
}