Parameter name completion: no insertion on just typing

This commit is contained in:
Valentin Kipyatkov
2015-06-17 21:26:57 +03:00
parent c0126b08c3
commit 22ad1389f5
10 changed files with 65 additions and 11 deletions
@@ -351,6 +351,10 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
override fun doComplete() {
assert(parameters.getCompletionType() == CompletionType.BASIC)
if (completionKind == CompletionKind.PARAMETER_NAME || completionKind == CompletionKind.ANNOTATION_TYPES_OR_PARAMETER_NAME) {
collector.suppressItemSelectionByCharsOnTyping = true
}
if (completionKind != CompletionKind.NAMED_ARGUMENTS_ONLY) {
collector.addDescriptorElements(referenceVariants, suppressAutoInsertion = false)
@@ -32,7 +32,9 @@ import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
public class KotlinCompletionCharFilter() : CharFilter() {
companion object {
public val ACCEPT_OPENING_BRACE: Key<Boolean> = Key("KotlinCompletionCharFilter.ACCEPT_OPENNING_BRACE")
public val ACCEPT_OPENING_BRACE: Key<Unit> = Key("KotlinCompletionCharFilter.ACCEPT_OPENNING_BRACE")
public val SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING: Key<Unit> = Key("KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING")
public val JUST_TYPING_PREFIX: Key<String> = Key("KotlinCompletionCharFilter.JUST_TYPING_PREFIX")
}
@@ -49,8 +51,11 @@ public class KotlinCompletionCharFilter() : CharFilter() {
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())) {
val currentItem = lookup.getCurrentItem()
// do not accept items by special chars in some special positions such as in the very beginning of function literal where name of the first parameter can be
if (isAutopopup && !lookup.isSelectionTouched()
&& (currentItem?.getUserData(SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING) != null || isInFunctionLiteralStart(completionParameters.getPosition()))) {
return Result.HIDE_LOOKUP
}
@@ -58,7 +63,6 @@ public class KotlinCompletionCharFilter() : CharFilter() {
return CharFilter.Result.ADD_TO_PREFIX
}
val currentItem = lookup.getCurrentItem()
if (!lookup.isSelectionTouched()) {
currentItem?.putUserData(JUST_TYPING_PREFIX, lookup.itemPattern(currentItem))
}
@@ -75,7 +79,7 @@ public class KotlinCompletionCharFilter() : CharFilter() {
}
'{' -> {
if (currentItem != null && currentItem.getUserData(ACCEPT_OPENING_BRACE) ?: false)
if (currentItem != null && currentItem.getUserData(ACCEPT_OPENING_BRACE) != null)
Result.SELECT_ITEM_AND_FINISH_LOOKUP
else
Result.HIDE_LOOKUP
@@ -207,7 +207,7 @@ public class LookupElementFactory(
element = element.withInsertHandler(insertHandler)
if (insertHandler is KotlinFunctionInsertHandler && insertHandler.lambdaInfo != null) {
element.putUserData<Boolean>(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, true)
element.putUserData(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, Unit)
}
return element
@@ -42,8 +42,8 @@ class LookupElementsCollector(
private val context: LookupElementsCollector.Context
) {
public enum class Context {
NORMAL
STRING_TEMPLATE_AFTER_DOLLAR
NORMAL,
STRING_TEMPLATE_AFTER_DOLLAR,
INFIX_CALL
}
@@ -60,6 +60,8 @@ class LookupElementsCollector(
public var isResultEmpty: Boolean = true
private set
public var suppressItemSelectionByCharsOnTyping: Boolean = false
public fun addDescriptorElements(descriptors: Iterable<DeclarationDescriptor>,
suppressAutoInsertion: Boolean, // auto-insertion suppression is used for elements that require adding an import
withReceiverCast: Boolean = false
@@ -137,7 +139,7 @@ class LookupElementsCollector(
public fun addElement(element: LookupElement) {
if (prefixMatcher.prefixMatches(element)) {
elements.add(object: LookupElementDecorator<LookupElement>(element) {
val decorated = object : LookupElementDecorator<LookupElement>(element) {
override fun handleInsert(context: InsertionContext) {
getDelegate().handleInsert(context)
@@ -155,7 +157,11 @@ class LookupElementsCollector(
}
}
})
}
if (suppressItemSelectionByCharsOnTyping) {
decorated.putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit)
}
elements.add(decorated)
}
}
@@ -200,7 +200,7 @@ class TypeInstantiationItems(
lookupElement = lookupElement.keepOldArgumentListOnTab()
}
if (baseInsertHandler.lambdaInfo != null) {
lookupElement.putUserData(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, true)
lookupElement.putUserData(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, Unit)
}
lookupElement = lookupElement.assignSmartCompletionPriority(SmartCompletionItemPriority.INSTANTIATION)
}
@@ -0,0 +1,7 @@
class FooBar
fun f(foo<caret>)
// ELEMENT: *
// INVOCATION_COUNT: 0
// CHAR: ':'
@@ -0,0 +1,7 @@
class FooBar
fun f(foo:<caret>)
// ELEMENT: *
// INVOCATION_COUNT: 0
// CHAR: ':'
@@ -0,0 +1,7 @@
class FooBar
fun f(foo<caret>)
// ELEMENT: *
// INVOCATION_COUNT: 0
// CHAR: ' '
@@ -0,0 +1,7 @@
class FooBar
fun f(foo <caret>)
// ELEMENT: *
// INVOCATION_COUNT: 0
// CHAR: ' '
@@ -265,6 +265,18 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
doTest(fileName);
}
@TestMetadata("NoInsertionOnTypingColon.kt")
public void testNoInsertionOnTypingColon() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/NoInsertionOnTypingColon.kt");
doTest(fileName);
}
@TestMetadata("NoInsertionOnTypingSpace.kt")
public void testNoInsertionOnTypingSpace() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/NoInsertionOnTypingSpace.kt");
doTest(fileName);
}
@TestMetadata("Simple.kt")
public void testSimple() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/parameterNameAndType/Simple.kt");