Smart completion inserts closing parenthesis as well
This commit is contained in:
@@ -40,6 +40,7 @@ trait SmartCompletionData{
|
||||
|
||||
enum class Tail {
|
||||
COMMA
|
||||
PARENTHESIS
|
||||
}
|
||||
|
||||
data class ExpectedTypeInfo(val `type`: JetType, val tail: Tail?)
|
||||
@@ -175,7 +176,7 @@ private fun calcArgumentExpectedTypes(expressionWithType: JetExpression, binding
|
||||
val parameters = candidate.getResultingDescriptor().getValueParameters()
|
||||
if (parameters.size <= argumentIndex) continue
|
||||
val parameterDescriptor = parameters[argumentIndex]
|
||||
val tail = if (argumentIndex == parameters.size - 1) null else Tail.COMMA
|
||||
val tail = if (argumentIndex == parameters.size - 1) Tail.PARENTHESIS else Tail.COMMA
|
||||
expectedTypes.add(ExpectedTypeInfo(parameterDescriptor.getType(), tail))
|
||||
}
|
||||
return expectedTypes
|
||||
@@ -493,11 +494,15 @@ private fun decorateLookupElement(lookupElement: LookupElement, tail: Tail?): Lo
|
||||
|
||||
Tail.COMMA -> object: LookupElementDecorator<LookupElement>(lookupElement) {
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
WithCommaInsertHandler.handleInsert(context, lookupElement)
|
||||
WithTailInsertHandler(',', true /*TODO: use code style option*/).handleInsert(context, lookupElement)
|
||||
}
|
||||
}
|
||||
|
||||
else -> throw RuntimeException("Unknown tail type")
|
||||
Tail.PARENTHESIS -> object: LookupElementDecorator<LookupElement>(lookupElement) {
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
WithTailInsertHandler(')', false).handleInsert(context, lookupElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -5,8 +5,9 @@ import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.openapi.editor.event.DocumentListener
|
||||
import com.intellij.openapi.editor.event.DocumentEvent
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
|
||||
object WithCommaInsertHandler : InsertHandler<LookupElement> {
|
||||
class WithTailInsertHandler(val tailChar: Char, val spaceAfter: Boolean) : InsertHandler<LookupElement> {
|
||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||
val document = context.getDocument()
|
||||
val caretModel = context.getEditor().getCaretModel()
|
||||
@@ -28,20 +29,23 @@ object WithCommaInsertHandler : InsertHandler<LookupElement> {
|
||||
}
|
||||
|
||||
document.addDocumentListener(documentListener)
|
||||
|
||||
item.handleInsert(context)
|
||||
PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(document)
|
||||
|
||||
document.removeDocumentListener(documentListener)
|
||||
|
||||
val moveCaret = caretModel.getOffset() == maxChangeOffset
|
||||
|
||||
if (maxChangeOffset < document.getTextLength() && document.getText(TextRange(maxChangeOffset, maxChangeOffset + 1)) == ",") {
|
||||
if (maxChangeOffset < document.getTextLength() && document.getText(TextRange(maxChangeOffset, maxChangeOffset + 1))[0] == tailChar) {
|
||||
document.deleteString(maxChangeOffset, maxChangeOffset + 1)
|
||||
|
||||
if (maxChangeOffset < document.getTextLength() && document.getText(TextRange(maxChangeOffset, maxChangeOffset + 1)) == " ") {
|
||||
if (spaceAfter && maxChangeOffset < document.getTextLength() && document.getText(TextRange(maxChangeOffset, maxChangeOffset + 1)) == " ") {
|
||||
document.deleteString(maxChangeOffset, maxChangeOffset + 1)
|
||||
}
|
||||
}
|
||||
|
||||
val textToInsert = ", " //TODO: code style option
|
||||
val textToInsert = if (spaceAfter) tailChar + " " else tailChar.toString()
|
||||
document.insertString(maxChangeOffset, textToInsert)
|
||||
if (moveCaret) {
|
||||
caretModel.moveToOffset(maxChangeOffset + textToInsert.length)
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(sss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(<caret>)
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(sss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
@@ -1,7 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(sss<caret>)
|
||||
foo(sss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(sss<caret>)
|
||||
foo(sss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(sss<caret>)
|
||||
foo(sss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(sss: String) {
|
||||
foo(sss<caret>)
|
||||
foo(sss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: sss
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fun foo(s: String){ }
|
||||
|
||||
fun bar(ss: String) {
|
||||
foo(ss<caret>)
|
||||
foo(ss)<caret>
|
||||
}
|
||||
|
||||
//ELEMENT: ss
|
||||
|
||||
+12
-8
@@ -16,17 +16,11 @@
|
||||
|
||||
package org.jetbrains.jet.completion.handlers;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
|
||||
import org.jetbrains.jet.completion.handlers.AbstractSmartCompletionHandlerTest;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@@ -66,6 +60,16 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
|
||||
doTest("idea/testData/completion/handlers/smart/ClassObjectMethod2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClosingParenthesis1.kt")
|
||||
public void testClosingParenthesis1() throws Exception {
|
||||
doTest("idea/testData/completion/handlers/smart/ClosingParenthesis1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClosingParenthesis2.kt")
|
||||
public void testClosingParenthesis2() throws Exception {
|
||||
doTest("idea/testData/completion/handlers/smart/ClosingParenthesis2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Comma1.kt")
|
||||
public void testComma1() throws Exception {
|
||||
doTest("idea/testData/completion/handlers/smart/Comma1.kt");
|
||||
|
||||
Reference in New Issue
Block a user