Smart completion inserts closing parenthesis as well

This commit is contained in:
Valentin Kipyatkov
2014-04-10 18:47:01 +04:00
parent f984dbc5b6
commit 5d8c5cfa31
12 changed files with 61 additions and 20 deletions
@@ -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)
}
}
}
}
@@ -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
@@ -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");