Completion auto-popup works at the start of function literal
This commit is contained in:
@@ -23,6 +23,10 @@ import org.jetbrains.kotlin.psi.JetFile
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.codeInsight.completion.CompletionService
|
||||
import com.intellij.codeInsight.completion.CompletionProgressIndicator
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.prevLeafSkipWhitespacesAndComments
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||
|
||||
public class KotlinCompletionCharFilter() : CharFilter() {
|
||||
class object {
|
||||
@@ -36,9 +40,19 @@ public class KotlinCompletionCharFilter() : CharFilter() {
|
||||
if (!lookup.isCompletion()) return null
|
||||
// it does not work in tests, so we use other way
|
||||
// val isAutopopup = CompletionService.getCompletionService().getCurrentCompletion().isAutopopupCompletion()
|
||||
val isAutopopup = (CompletionService.getCompletionService().getCurrentCompletion() as CompletionProgressIndicator).getParameters().getInvocationCount() == 0
|
||||
val completionParameters = (CompletionService.getCompletionService().getCurrentCompletion() as CompletionProgressIndicator).getParameters()
|
||||
val isAutopopup = completionParameters.getInvocationCount() == 0
|
||||
|
||||
if (Character.isJavaIdentifierPart(c) || c == ':' /* used in '::xxx'*/ || c == '@') {
|
||||
if (Character.isJavaIdentifierPart(c) || c == '@') {
|
||||
return CharFilter.Result.ADD_TO_PREFIX
|
||||
}
|
||||
|
||||
// do not accept items by special chars in the very beginning of function literal where name of the first parameter can be
|
||||
if (isAutopopup && !lookup.isSelectionTouched() && isInFunctionLiteralStart(completionParameters.getPosition())) {
|
||||
return Result.HIDE_LOOKUP
|
||||
}
|
||||
|
||||
if (c == ':' /* used in '::xxx'*/) {
|
||||
return CharFilter.Result.ADD_TO_PREFIX
|
||||
}
|
||||
|
||||
@@ -70,4 +84,14 @@ public class KotlinCompletionCharFilter() : CharFilter() {
|
||||
else -> CharFilter.Result.HIDE_LOOKUP
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInFunctionLiteralStart(position: PsiElement): Boolean {
|
||||
var prev = position.prevLeafSkipWhitespacesAndComments()
|
||||
if (prev?.getNode()?.getElementType() == JetTokens.LPAR) {
|
||||
prev = prev?.prevLeafSkipWhitespacesAndComments()
|
||||
}
|
||||
if (prev?.getNode()?.getElementType() != JetTokens.LBRACE) return false
|
||||
val functionLiteral = prev!!.getParent() as? JetFunctionLiteral ?: return false
|
||||
return functionLiteral.getLBrace() == prev
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,9 +248,6 @@ public class KotlinCompletionContributor : CompletionContributor() {
|
||||
// no auto-popup on typing after "val", "var" and "fun" because it's likely the name of the declaration which is being typed by user
|
||||
if (invocationCount == 0 && isInExtensionReceiver(position)) return true
|
||||
|
||||
// no auto-popup on typing in the very beginning of function literal where name of the first parameter can be
|
||||
if (invocationCount == 0 && isInFunctionLiteralStart(position)) return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -267,16 +264,6 @@ public class KotlinCompletionContributor : CompletionContributor() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInFunctionLiteralStart(position: PsiElement): Boolean {
|
||||
var prev = position.prevLeafSkipWhitespacesAndComments()
|
||||
if (prev?.getNode()?.getElementType() == JetTokens.LPAR) {
|
||||
prev = prev?.prevLeafSkipWhitespacesAndComments()
|
||||
}
|
||||
if (prev?.getNode()?.getElementType() != JetTokens.LBRACE) return false
|
||||
val functionLiteral = prev!!.getParent() as? JetFunctionLiteral ?: return false
|
||||
return functionLiteral.getLBrace() == prev
|
||||
}
|
||||
|
||||
private fun isAtEndOfLine(offset: Int, document: Document): Boolean {
|
||||
var i = offset
|
||||
val chars = document.getCharsSequence()
|
||||
|
||||
@@ -3,4 +3,5 @@ fun bar() {
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// NUMBER: 0
|
||||
// EXIST: bar
|
||||
// EXIST: null
|
||||
|
||||
@@ -3,4 +3,5 @@ fun bar() {
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// NUMBER: 0
|
||||
// EXIST: bar
|
||||
// EXIST: null
|
||||
|
||||
@@ -5,4 +5,5 @@ fun bar() {
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// NUMBER: 0
|
||||
// EXIST: bar
|
||||
// EXIST: null
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: (String) -> Unit){}
|
||||
|
||||
fun bar() {
|
||||
foo { p<caret> }
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// ELEMENT: *
|
||||
// CHAR: ' '
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: (String) -> Unit){}
|
||||
|
||||
fun bar() {
|
||||
foo { p <caret> }
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// ELEMENT: *
|
||||
// CHAR: ' '
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: (String) -> Unit){}
|
||||
|
||||
fun bar() {
|
||||
foo { (p<caret> }
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// ELEMENT: *
|
||||
// CHAR: ':'
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: (String) -> Unit){}
|
||||
|
||||
fun bar() {
|
||||
foo { (p:<caret> }
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// ELEMENT: *
|
||||
// CHAR: ':'
|
||||
@@ -0,0 +1,9 @@
|
||||
fun bar() {
|
||||
val handler = { p<caret>
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// ELEMENT: *
|
||||
// CHAR: ' '
|
||||
@@ -0,0 +1,9 @@
|
||||
fun bar() {
|
||||
val handler = { p <caret>
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 0
|
||||
// ELEMENT: *
|
||||
// CHAR: ' '
|
||||
+18
@@ -126,6 +126,24 @@ public class CompletionCharFilterTestGenerated extends AbstractCompletionCharFil
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionLiteralParameter1.kt")
|
||||
public void testFunctionLiteralParameter1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/charFilter/FunctionLiteralParameter1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionLiteralParameter2.kt")
|
||||
public void testFunctionLiteralParameter2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/charFilter/FunctionLiteralParameter2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionLiteralParameter3.kt")
|
||||
public void testFunctionLiteralParameter3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/charFilter/FunctionLiteralParameter3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionWithLambdaArg1.kt")
|
||||
public void testFunctionWithLambdaArg1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/handlers/charFilter/FunctionWithLambdaArg1.kt");
|
||||
|
||||
Reference in New Issue
Block a user