diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt index fec48f84851..1b11cc58bd2 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt @@ -189,13 +189,17 @@ class BasicCompletionSession( filter } + override fun shouldDisableAutoPopup(): Boolean { + return isStartOfExtensionReceiverFor() is KtProperty && wasAutopopupRecentlyCancelled(parameters) + } + override fun doComplete() { val declaration = isStartOfExtensionReceiverFor() if (declaration != null) { completeDeclarationNameFromUnresolvedOrOverride(declaration) if (declaration is KtProperty) { - completeVariableName(declaration.modifierList?.hasModifier(KtTokens.LATEINIT_KEYWORD) == true) + completeParameterOrVarNameAndType(declaration.modifierList?.hasModifier(KtTokens.LATEINIT_KEYWORD) == true) } // 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 @@ -491,26 +495,11 @@ class BasicCompletionSession( else -> null } } - - private fun completeVariableName(withType: Boolean) { - val variableNameAndTypeCompletion = VariableOrParameterNameWithTypeCompletion(collector, basicLookupElementFactory, prefixMatcher, resolutionFacade, withType) - - // if we are typing parameter name, restart completion each time we type an upper case letter because new suggestions will appear (previous words can be used as user prefix) - val prefixPattern = StandardPatterns.string().with(object : PatternCondition("Prefix ends with uppercase letter") { - override fun accepts(prefix: String, context: ProcessingContext?) = prefix.isNotEmpty() && prefix.last().isUpperCase() - }) - collector.restartCompletionOnPrefixChange(prefixPattern) - - variableNameAndTypeCompletion.addFromParametersInFile(position, resolutionFacade, isVisibleFilterCheckAlways) - flushToResultSet() - - variableNameAndTypeCompletion.addFromImportedClasses(position, bindingContext, isVisibleFilterCheckAlways) - flushToResultSet() - - variableNameAndTypeCompletion.addFromAllClasses(parameters, indicesHelper(false)) - } } + private fun wasAutopopupRecentlyCancelled(parameters: CompletionParameters) = + LookupCancelWatcher.getInstance(project).wasAutoPopupRecentlyCancelled(parameters.editor, position.startOffset) + private val KEYWORDS_ONLY = object : CompletionKind { override val descriptorKindFilter: DescriptorKindFilter? get() = null @@ -650,9 +639,7 @@ class BasicCompletionSession( completeDeclarationNameFromUnresolvedOrOverride(declaration) when (declaration) { - is KtParameter -> - completeParameterNameAndType() - + is KtParameter -> completeParameterOrVarNameAndType(withType = true) is KtClassOrObject -> { if (declaration.isTopLevel()) { completeTopLevelClassName() @@ -663,13 +650,7 @@ class BasicCompletionSession( override fun shouldDisableAutoPopup(): Boolean { if (TemplateManager.getInstance(project).getActiveTemplate(parameters.editor) != null) return true - - if (declaration() is KtParameter) { - if (LookupCancelWatcher.getInstance(project).wasAutoPopupRecentlyCancelled(parameters.editor, position.startOffset)) { - return true - } - } - + if (declaration() is KtParameter && wasAutopopupRecentlyCancelled(parameters)) return true return false } @@ -680,24 +661,6 @@ class BasicCompletionSession( return sorter } - private fun completeParameterNameAndType() { - val parameterNameAndTypeCompletion = VariableOrParameterNameWithTypeCompletion(collector, basicLookupElementFactory, prefixMatcher, resolutionFacade, true) - - // if we are typing parameter name, restart completion each time we type an upper case letter because new suggestions will appear (previous words can be used as user prefix) - val prefixPattern = StandardPatterns.string().with(object : PatternCondition("Prefix ends with uppercase letter") { - override fun accepts(prefix: String, context: ProcessingContext?) = prefix.isNotEmpty() && prefix.last().isUpperCase() - }) - collector.restartCompletionOnPrefixChange(prefixPattern) - - parameterNameAndTypeCompletion.addFromParametersInFile(position, resolutionFacade, isVisibleFilterCheckAlways) - flushToResultSet() - - parameterNameAndTypeCompletion.addFromImportedClasses(position, bindingContext, isVisibleFilterCheckAlways) - flushToResultSet() - - parameterNameAndTypeCompletion.addFromAllClasses(parameters, indicesHelper(false)) - } - private fun completeTopLevelClassName() { val name = parameters.originalFile.virtualFile.nameWithoutExtension if (!(Name.isValidIdentifier(name) && Name.identifier(name).render() == name && name[0].isUpperCase())) return @@ -808,6 +771,26 @@ class BasicCompletionSession( flushToResultSet() } } + + private fun completeParameterOrVarNameAndType(withType: Boolean) { + val nameWithTypeCompletion = + VariableOrParameterNameWithTypeCompletion(collector, basicLookupElementFactory, prefixMatcher, resolutionFacade, withType) + + // if we are typing parameter name, restart completion each time we type an upper case letter + // because new suggestions will appear (previous words can be used as user prefix) + val prefixPattern = StandardPatterns.string().with(object : PatternCondition("Prefix ends with uppercase letter") { + override fun accepts(prefix: String, context: ProcessingContext?) = prefix.isNotEmpty() && prefix.last().isUpperCase() + }) + collector.restartCompletionOnPrefixChange(prefixPattern) + + nameWithTypeCompletion.addFromParametersInFile(position, resolutionFacade, isVisibleFilterCheckAlways) + flushToResultSet() + + nameWithTypeCompletion.addFromImportedClasses(position, bindingContext, isVisibleFilterCheckAlways) + flushToResultSet() + + nameWithTypeCompletion.addFromAllClasses(parameters, indicesHelper(false)) + } } private val USUALLY_START_UPPER_CASE = DescriptorKindFilter(DescriptorKindFilter.CLASSIFIERS_MASK or DescriptorKindFilter.FUNCTIONS_MASK,