diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/WithTailInsertHandler.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/WithTailInsertHandler.kt index 99904e18a78..be1cc8472e6 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/WithTailInsertHandler.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/WithTailInsertHandler.kt @@ -21,6 +21,7 @@ import com.intellij.codeInsight.completion.InsertHandler import com.intellij.codeInsight.completion.InsertionContext import com.intellij.codeInsight.lookup.Lookup import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.openapi.editor.Document import com.intellij.psi.PsiDocumentManager import org.jetbrains.kotlin.idea.completion.KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion @@ -55,8 +56,11 @@ class WithTailInsertHandler(val tailText: String, //TODO: analyze parenthesis balance to decide whether to replace or not var insert = true if (overwriteText) { - var offset = document.charsSequence.skipSpacesAndLineBreaks(tailOffset) - if (document.isTextAt(offset, tailText)) { + var offset = tailOffset + if (tailText != " ") { + offset = document.charsSequence.skipSpacesAndLineBreaks(offset) + } + if (shouldOverwriteChar(document, offset)) { insert = false offset += tailText.length tailOffset = offset @@ -85,6 +89,12 @@ class WithTailInsertHandler(val tailText: String, } } + private fun shouldOverwriteChar(document: Document, offset: Int): Boolean { + if (!document.isTextAt(offset, tailText)) return false + if (tailText == " " && document.charsSequence.isCharAt(offset + 1, '}')) return false // do not overwrite last space before '}' + return true + } + companion object { val COMMA = WithTailInsertHandler(",", spaceBefore = false, spaceAfter = true /*TODO: use code style option*/) val RPARENTH = WithTailInsertHandler(")", spaceBefore = false, spaceAfter = false) @@ -92,6 +102,6 @@ class WithTailInsertHandler(val tailText: String, val RBRACE = WithTailInsertHandler("}", spaceBefore = true, spaceAfter = false) val ELSE = WithTailInsertHandler("else", spaceBefore = true, spaceAfter = true) val EQ = WithTailInsertHandler("=", spaceBefore = true, spaceAfter = true) /*TODO: use code style options*/ - val SPACE = WithTailInsertHandler(" ", spaceBefore = false, spaceAfter = false, overwriteText = false) + val SPACE = WithTailInsertHandler(" ", spaceBefore = false, spaceAfter = false, overwriteText = true) } } diff --git a/idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt b/idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt new file mode 100644 index 00000000000..0157a3d39ec --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt @@ -0,0 +1,5 @@ +val v: Boolean = run { + return true +} + +// ELEMENT: "return@run" \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt.after b/idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt.after new file mode 100644 index 00000000000..04307fffee8 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt.after @@ -0,0 +1,5 @@ +val v: Boolean = run { + return@run true +} + +// ELEMENT: "return@run" \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt b/idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt new file mode 100644 index 00000000000..c83ea3652f4 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt @@ -0,0 +1,4 @@ +clinterface MyClass + +// ELEMENT: "class" +// CHAR: '\t' \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt.after b/idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt.after new file mode 100644 index 00000000000..408077d9804 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt.after @@ -0,0 +1,4 @@ +class MyClass + +// ELEMENT: "class" +// CHAR: '\t' \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index 2989d2ea1e0..65a448eb412 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -31,6 +31,12 @@ import java.util.regex.Pattern; @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletionHandlerTest { + @TestMetadata("AddLabelToReturn.kt") + public void testAddLabelToReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/AddLabelToReturn.kt"); + doTest(fileName); + } + public void testAllFilesPresentInBasic() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic"), Pattern.compile("^(.+)\\.kt$"), true); } @@ -53,6 +59,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion doTest(fileName); } + @TestMetadata("ClassKeywordBeforeName.kt") + public void testClassKeywordBeforeName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/ClassKeywordBeforeName.kt"); + doTest(fileName); + } + @TestMetadata("ClassWithClassObject.kt") public void testClassWithClassObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/ClassWithClassObject.kt");