From 4fab29b6484140d1fd759008fbb6c6f850ea9806 Mon Sep 17 00:00:00 2001 From: fitermay Date: Thu, 25 May 2017 23:09:56 -0400 Subject: [PATCH] KT-18006 Don't cut off trailing new lines. Make behavior consistent with Java literal copy/paste --- .../idea/editor/KotlinLiteralCopyPasteProcessor.kt | 13 ++++++++++--- .../plainTextLiteral/TrailingLines.expected.kt | 6 ++++++ .../copyPaste/plainTextLiteral/TrailingLines.kt | 1 + .../copyPaste/plainTextLiteral/TrailingLines.txt | 10 ++++++++++ .../LiteralTextToKotlinCopyPasteTestGenerated.java | 6 ++++++ .../AbstractLiteralTextToKotlinCopyPasteTest.kt | 3 ++- .../kotlin/idea/editor/TemplateTokenSequenceTest.kt | 2 +- 7 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 idea/testData/copyPaste/plainTextLiteral/TrailingLines.expected.kt create mode 100644 idea/testData/copyPaste/plainTextLiteral/TrailingLines.kt create mode 100644 idea/testData/copyPaste/plainTextLiteral/TrailingLines.txt diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinLiteralCopyPasteProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinLiteralCopyPasteProcessor.kt index 2dda46750d7..95e2b982cfb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinLiteralCopyPasteProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinLiteralCopyPasteProcessor.kt @@ -135,14 +135,21 @@ class KotlinLiteralCopyPasteProcessor : CopyPastePreProcessor { return if (beginTp.isSingleQuoted()) { val res = StringBuilder() + val lineBreak = "\\n\"+\n \"" + var endsInLineBreak = false TemplateTokenSequence(text).forEach { when (it) { is LiteralChunk -> StringUtil.escapeStringCharacters(it.text.length, it.text, "\$\"", res) is EntryChunk -> res.append(it.text) - is NewLineChunk -> res.append("\\n\"+\n \"") + is NewLineChunk -> res.append(lineBreak) } + endsInLineBreak = it is NewLineChunk + } + return if (endsInLineBreak){ + res.removeSuffix(lineBreak).toString() + "\\n" + } else{ + res.toString() } - res.toString() } else { val tripleQuoteRe = Regex("[\"]{3,}") @@ -211,7 +218,7 @@ private class TemplateTokenSequence(private val inputString: String) : Sequence< } private suspend fun SequenceBuilder.yieldLiteral(chunk: String) { - val splitLines = LineTokenizer.tokenize(chunk, false, true) + val splitLines = LineTokenizer.tokenize(chunk, false, false) for (i in 0..splitLines.size - 1) { if (i != 0) { yield(NewLineChunk) diff --git a/idea/testData/copyPaste/plainTextLiteral/TrailingLines.expected.kt b/idea/testData/copyPaste/plainTextLiteral/TrailingLines.expected.kt new file mode 100644 index 00000000000..ed5580561bf --- /dev/null +++ b/idea/testData/copyPaste/plainTextLiteral/TrailingLines.expected.kt @@ -0,0 +1,6 @@ +val a = "a\n" + + "b\n" + + "c\n" + + "\n" + + "\n" + + "\n" \ No newline at end of file diff --git a/idea/testData/copyPaste/plainTextLiteral/TrailingLines.kt b/idea/testData/copyPaste/plainTextLiteral/TrailingLines.kt new file mode 100644 index 00000000000..0a7189cb654 --- /dev/null +++ b/idea/testData/copyPaste/plainTextLiteral/TrailingLines.kt @@ -0,0 +1 @@ +val a = "" \ No newline at end of file diff --git a/idea/testData/copyPaste/plainTextLiteral/TrailingLines.txt b/idea/testData/copyPaste/plainTextLiteral/TrailingLines.txt new file mode 100644 index 00000000000..b0f86f5ab7f --- /dev/null +++ b/idea/testData/copyPaste/plainTextLiteral/TrailingLines.txt @@ -0,0 +1,10 @@ +a +b +c + + + +d +e +f +g \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/LiteralTextToKotlinCopyPasteTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/LiteralTextToKotlinCopyPasteTestGenerated.java index 17bf4e81daa..9e587aa6c6a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/LiteralTextToKotlinCopyPasteTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/conversion/copy/LiteralTextToKotlinCopyPasteTestGenerated.java @@ -66,6 +66,12 @@ public class LiteralTextToKotlinCopyPasteTestGenerated extends AbstractLiteralTe doTest(fileName); } + @TestMetadata("TrailingLines.txt") + public void testTrailingLines() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/plainTextLiteral/TrailingLines.txt"); + doTest(fileName); + } + @TestMetadata("WithBackslashes.txt") public void testWithBackslashes() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/copyPaste/plainTextLiteral/WithBackslashes.txt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/AbstractLiteralTextToKotlinCopyPasteTest.kt b/idea/tests/org/jetbrains/kotlin/idea/editor/AbstractLiteralTextToKotlinCopyPasteTest.kt index 2c5df29e195..50797d6b43a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/AbstractLiteralTextToKotlinCopyPasteTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/AbstractLiteralTextToKotlinCopyPasteTest.kt @@ -38,7 +38,8 @@ abstract class AbstractLiteralTextToKotlinCopyPasteTest : AbstractCopyPasteTest( myFixture.configureByFiles(testName + ".txt") val fileText = myFixture.editor.document.text - myFixture.editor.selectionModel.setSelection(0, fileText.length) + if (!myFixture.editor.selectionModel.hasSelection()) + myFixture.editor.selectionModel.setSelection(0, fileText.length) myFixture.performEditorAction(IdeActions.ACTION_COPY) configureTargetFile(testName + ".kt") diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/TemplateTokenSequenceTest.kt b/idea/tests/org/jetbrains/kotlin/idea/editor/TemplateTokenSequenceTest.kt index 3447fd3de09..35df8131e2d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/TemplateTokenSequenceTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/TemplateTokenSequenceTest.kt @@ -44,7 +44,7 @@ class TemplateTokenSequenceTest:UsefulTestCase() { //last empty line is skipped fun `test trailing new lines`(){ - doTest("literal\n\n", "LITERAL_CHUNK(literal)NEW_LINE()") + doTest("literal\n\n", "LITERAL_CHUNK(literal)NEW_LINE()NEW_LINE()") }