diff --git a/platform/polySymbols/api-dump-experimental.txt b/platform/polySymbols/api-dump-experimental.txt index f937893cb074..d369c1f17dbd 100644 --- a/platform/polySymbols/api-dump-experimental.txt +++ b/platform/polySymbols/api-dump-experimental.txt @@ -234,6 +234,7 @@ - s:create(java.lang.String,I,com.intellij.polySymbols.PolySymbol,kotlin.jvm.functions.Function1):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:getAliases():java.util.Set - a:getApiStatus():com.intellij.polySymbols.PolySymbolApiStatus +- a:getAsyncCustomizers():java.util.List - a:getCaseSensitive():Z - a:getCompleteAfterChars():java.util.Set - a:getDisplayName():java.lang.String @@ -247,12 +248,15 @@ - s:getPsiElement(com.intellij.codeInsight.lookup.LookupElement):com.intellij.psi.PsiElement - a:getSymbol():com.intellij.polySymbols.PolySymbol - a:getTailText():java.lang.String +- a:getTailTextGreyed():Z - a:getTypeText():java.lang.String +- a:getTypeTextGreyed():Z - a:isCompleteAfterInsert():Z - a:withAliasAdded(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withAliasesAdded(java.util.Set):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withAliasesReplaced(java.util.Set):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withApiStatus(com.intellij.polySymbols.PolySymbolApiStatus):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem +- a:withAsyncCustomizer(kotlin.jvm.functions.Function1):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withCaseSensitive(Z):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withCompleteAfterChar(C):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withCompleteAfterCharsAdded(java.util.List):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem @@ -272,8 +276,9 @@ - a:withProximity(I):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withSymbol(com.intellij.polySymbols.PolySymbol):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withTailText(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem +- a:withTailText(java.lang.String,Z):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:withTypeText(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem -- a:withTypeText(kotlin.jvm.functions.Function0):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem +- a:withTypeText(java.lang.String,Z):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem *f:com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem$Companion - f:builder(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - f:builder(java.lang.String,I):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder @@ -289,6 +294,7 @@ *:com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:aliases(java.util.Set):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:apiStatus(com.intellij.polySymbols.PolySymbolApiStatus):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder +- a:asyncCustomizer(kotlin.jvm.functions.Function1):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:build():com.intellij.polySymbols.completion.PolySymbolCodeCompletionItem - a:caseSensitive(Z):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:completeAfterChars(java.util.Set):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder @@ -307,7 +313,9 @@ - a:getProximity():java.lang.Integer - a:getSymbol():com.intellij.polySymbols.PolySymbol - a:getTailText():java.lang.String +- a:getTailTextGreyed():Z - a:getTypeText():java.lang.String +- a:getTypeTextGreyed():Z - a:icon(javax.swing.Icon):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:insertHandler(com.intellij.codeInsight.completion.InsertHandler):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:insertHandler(com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemInsertHandler):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder @@ -318,8 +326,9 @@ - a:restartCompletionOnPrefixChange(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:symbol(com.intellij.polySymbols.PolySymbol):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:tailText(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder +- a:tailText(java.lang.String,Z):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder - a:typeText(java.lang.String):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder -- a:typeText(kotlin.jvm.functions.Function0):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder +- a:typeText(java.lang.String,Z):com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemBuilder *:com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemInsertHandler - *sf:Companion:com.intellij.polySymbols.completion.PolySymbolCodeCompletionItemInsertHandler$Companion - getPriority():com.intellij.polySymbols.PolySymbol$Priority diff --git a/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItem.kt b/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItem.kt index 55ac845dc71e..655ddf283bb8 100644 --- a/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItem.kt +++ b/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItem.kt @@ -27,7 +27,9 @@ interface PolySymbolCodeCompletionItem { val offset: Int val icon: Icon? val typeText: String? + val typeTextGreyed: Boolean val tailText: String? + val tailTextGreyed: Boolean val caseSensitive: Boolean @get:JvmName("isCompleteAfterInsert") @@ -41,6 +43,8 @@ interface PolySymbolCodeCompletionItem { val symbol: PolySymbol? val insertHandler: PolySymbolCodeCompletionItemInsertHandler? + val asyncCustomizers: List PolySymbolCodeCompletionItem> + fun withPrefix(prefix: String): PolySymbolCodeCompletionItem fun addToResult( @@ -75,10 +79,14 @@ interface PolySymbolCodeCompletionItem { fun withTypeText(typeText: String?): PolySymbolCodeCompletionItem - fun withTypeText(typeTextProvider: () -> String?): PolySymbolCodeCompletionItem + fun withTypeText(typeText: String?, greyed: Boolean): PolySymbolCodeCompletionItem fun withTailText(tailText: String?): PolySymbolCodeCompletionItem + fun withTailText(tailText: String?, greyed: Boolean): PolySymbolCodeCompletionItem + + fun withAsyncCustomizer(asyncCustomizer: PolySymbolCodeCompletionItem.() -> PolySymbolCodeCompletionItem): PolySymbolCodeCompletionItem + fun withCaseSensitive(value: Boolean): PolySymbolCodeCompletionItem fun withCompleteAfterChar(char: Char): PolySymbolCodeCompletionItem diff --git a/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItemBuilder.kt b/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItemBuilder.kt index 7f9974e45099..599d57ad41eb 100644 --- a/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItemBuilder.kt +++ b/platform/polySymbols/src/com/intellij/polySymbols/completion/PolySymbolCodeCompletionItemBuilder.kt @@ -12,7 +12,9 @@ interface PolySymbolCodeCompletionItemBuilder { val offset: Int val icon: Icon? val typeText: String? + val typeTextGreyed: Boolean val tailText: String? + val tailTextGreyed: Boolean val caseSensitive: Boolean val completeAfterInsert: Boolean @@ -29,9 +31,11 @@ interface PolySymbolCodeCompletionItemBuilder { fun offset(value: Int): PolySymbolCodeCompletionItemBuilder fun icon(value: Icon?): PolySymbolCodeCompletionItemBuilder fun typeText(value: String?): PolySymbolCodeCompletionItemBuilder - fun typeText(provider: () -> String?): PolySymbolCodeCompletionItemBuilder + fun typeText(value: String?, greyed: Boolean): PolySymbolCodeCompletionItemBuilder fun tailText(value: String?): PolySymbolCodeCompletionItemBuilder + fun tailText(value: String?, greyed: Boolean): PolySymbolCodeCompletionItemBuilder fun caseSensitive(value: Boolean): PolySymbolCodeCompletionItemBuilder + fun asyncCustomizer(value: PolySymbolCodeCompletionItem.() -> PolySymbolCodeCompletionItem): PolySymbolCodeCompletionItemBuilder fun completeAfterInsert(value: Boolean): PolySymbolCodeCompletionItemBuilder fun completeAfterChars(value: Set): PolySymbolCodeCompletionItemBuilder diff --git a/platform/polySymbols/src/com/intellij/polySymbols/completion/impl/PolySymbolCodeCompletionItemImpl.kt b/platform/polySymbols/src/com/intellij/polySymbols/completion/impl/PolySymbolCodeCompletionItemImpl.kt index 3cf43ab521b5..f7c9af4418cd 100644 --- a/platform/polySymbols/src/com/intellij/polySymbols/completion/impl/PolySymbolCodeCompletionItemImpl.kt +++ b/platform/polySymbols/src/com/intellij/polySymbols/completion/impl/PolySymbolCodeCompletionItemImpl.kt @@ -28,10 +28,12 @@ internal data class PolySymbolCodeCompletionItemImpl( override val apiStatus: PolySymbolApiStatus = PolySymbolApiStatus.Stable, override val aliases: Set = emptySet(), override val icon: Icon? = null, - val typeTextStatic: String? = null, - val typeTextProvider: (() -> String?)? = null, + override val typeText: String? = null, + override val typeTextGreyed: Boolean = true, override val tailText: String? = null, + override val tailTextGreyed: Boolean = true, override val caseSensitive: Boolean = true, + override val asyncCustomizers: List PolySymbolCodeCompletionItem> = emptyList(), override val insertHandler: PolySymbolCodeCompletionItemInsertHandler? = null, @get:ApiStatus.Internal val stopSequencePatternEvaluation: Boolean = false, @@ -39,8 +41,6 @@ internal data class PolySymbolCodeCompletionItemImpl( val restartCompletionOnPrefixChange: Set = emptySet(), ) : PolySymbolCodeCompletionItem { - override val typeText: String? get() = typeTextProvider?.invoke() ?: typeTextStatic - override fun addToResult( parameters: CompletionParameters, result: CompletionResultSet, @@ -52,31 +52,10 @@ internal data class PolySymbolCodeCompletionItemImpl( completionPrefix.substring(offset) == name) return val priorityOffset = baselinePriorityValue - PolySymbol.Priority.NORMAL.value - val deprecatedOrObsolete = apiStatus.isDeprecatedOrObsolete() LookupElementBuilder .create(wrapSymbolForDocumentation(symbol, parameters.position)?.createPointer() ?: name, name) .withLookupStrings(aliases) - .withIcon(icon?.scaleToHeight(16)) - .withTypeText(typeTextStatic, true) - .let { - if (typeTextProvider != null) - it.withExpensiveRenderer(object : LookupElementRenderer() { - override fun renderElement(element: LookupElement, presentation: LookupElementPresentation) { - element.renderElement(presentation) - typeTextProvider()?.let { presentation.typeText = it } - } - }) - else it - } - .withTailText(tailText, true) .withCaseSensitivity(caseSensitive) - .withBoldness(!deprecatedOrObsolete && priority != null && priority >= PolySymbol.Priority.HIGHEST) - .withStrikeoutness(deprecatedOrObsolete) - .let { - if (displayName != null) - it.withPresentableText(displayName) - else it - } .withInsertHandler { insertionContext, completionItem -> val invokeCompletion = completeAfterInsert || completeAfterChars.contains(insertionContext.completionChar) insertHandler?.prepare(insertionContext, completionItem, invokeCompletion)?.run() @@ -86,12 +65,34 @@ internal data class PolySymbolCodeCompletionItemImpl( .invokeCompletion(parameters.originalFile.project, parameters.editor) } } + } + .withRenderer(object : LookupElementRenderer() { + override fun renderElement( + element: LookupElement, + presentation: LookupElementPresentation, + ) { + renderPresentation(priorityOffset, presentation) + } + }) + .let { + if (asyncCustomizers.isNotEmpty()) + it.withExpensiveRenderer(object : LookupElementRenderer() { + override fun renderElement(element: LookupElement, presentation: LookupElementPresentation) { + element.renderElement(presentation) + val completionItem = asyncCustomizers + .fold(this@PolySymbolCodeCompletionItemImpl as PolySymbolCodeCompletionItem) { item, customizer -> + customizer(item) + } + (completionItem as PolySymbolCodeCompletionItemImpl).renderPresentation(priorityOffset, presentation) + } + }) + else it }.let { if (completeAfterChars.isNotEmpty()) it.withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE) else it }.let { - val priorityValue = if (deprecatedOrObsolete) PolySymbol.Priority.LOWEST.value + val priorityValue = if (apiStatus.isDeprecatedOrObsolete()) PolySymbol.Priority.LOWEST.value else (priority ?: PolySymbol.Priority.NORMAL).value + priorityOffset PrioritizedLookupElement.withPriority(it, priorityValue) }.let { @@ -112,6 +113,21 @@ internal data class PolySymbolCodeCompletionItemImpl( } } + private fun renderPresentation(priorityOffset: Double, presentation: LookupElementPresentation) { + val deprecatedOrObsolete = apiStatus.isDeprecatedOrObsolete() + presentation.itemText = displayName ?: name + presentation.isItemTextBold = + !deprecatedOrObsolete && priority != null && (priority.value + priorityOffset) >= PolySymbol.Priority.HIGHEST.value + presentation.isStrikeout = deprecatedOrObsolete + presentation.icon = icon?.scaleToHeight(16) + presentation.clearTail() + if (tailText != null) { + presentation.appendTailText(tailText, tailTextGreyed) + } + presentation.typeText = typeText + presentation.isTypeGrayed = typeTextGreyed + } + private fun wrapSymbolForDocumentation(symbol: PolySymbol?, location: PsiElement) = when (symbol) { is PsiSourcedPolySymbol -> PsiSourcedCodeCompletionPolySymbolWithDocumentation(symbol, location) @@ -167,14 +183,17 @@ internal data class PolySymbolCodeCompletionItemImpl( copy(icon = icon) override fun withTypeText(typeText: String?): PolySymbolCodeCompletionItem = - copy(typeTextStatic = typeText) + copy(typeText = typeText) - override fun withTypeText(typeTextProvider: () -> String?): PolySymbolCodeCompletionItem = - copy(typeTextProvider = typeTextProvider) + override fun withTypeText(typeText: String?, greyed: Boolean): PolySymbolCodeCompletionItem = + copy(typeText = typeText, typeTextGreyed = greyed) override fun withTailText(tailText: String?): PolySymbolCodeCompletionItem = copy(tailText = tailText) + override fun withTailText(tailText: String?, greyed: Boolean): PolySymbolCodeCompletionItem = + copy(tailText = tailText, tailTextGreyed = greyed) + override fun withCaseSensitive(value: Boolean): PolySymbolCodeCompletionItem = copy(caseSensitive = value) @@ -184,6 +203,9 @@ internal data class PolySymbolCodeCompletionItemImpl( override fun withCompleteAfterCharsAdded(chars: List): PolySymbolCodeCompletionItem = copy(completeAfterChars = if (!completeAfterInsert) completeAfterChars + chars else emptySet()) + override fun withAsyncCustomizer(asyncCustomizer: PolySymbolCodeCompletionItem.() -> PolySymbolCodeCompletionItem): PolySymbolCodeCompletionItem = + copy(asyncCustomizers = asyncCustomizers + asyncCustomizer) + override fun withInsertHandlerReplaced(insertHandler: PolySymbolCodeCompletionItemInsertHandler?): PolySymbolCodeCompletionItem = copy(insertHandler = insertHandler) @@ -213,13 +235,13 @@ internal data class PolySymbolCodeCompletionItemImpl( proximity: Int? = this.proximity, apiStatus: PolySymbolApiStatus = this.apiStatus, icon: Icon? = this.icon, - typeText: String? = null, + typeText: String? = this.typeText, tailText: String? = this.tailText, ): PolySymbolCodeCompletionItem = copy(name = name, offset = offset, completeAfterInsert = completeAfterInsert, completeAfterChars = if (!completeAfterInsert) completeAfterChars else emptySet(), displayName = displayName, symbol = symbol, priority = priority, proximity = proximity, - apiStatus = apiStatus, icon = icon, typeTextStatic = typeText ?: typeTextStatic, + apiStatus = apiStatus, icon = icon, typeText = typeText, tailText = tailText) class BuilderImpl( @@ -239,20 +261,21 @@ internal data class PolySymbolCodeCompletionItemImpl( it.icon ?: PolySymbolDefaultIconProvider.get(it.kind) } - private var typeTextStatic: String? = null - private var typeTextProvider: (() -> String?)? = null + override var typeText: String? = null + override var typeTextGreyed: Boolean = true override var tailText: String? = null + override var tailTextGreyed: Boolean = true override var caseSensitive: Boolean = true override var insertHandler: PolySymbolCodeCompletionItemInsertHandler? = null + private var asyncCustomizers: MutableList PolySymbolCodeCompletionItem> = mutableListOf() private var stopSequencePatternEvaluation: Boolean = false private var restartCompletionOnAnyPrefixChange: Boolean = false private var restartCompletionOnPrefixChange: MutableSet = mutableSetOf() - override val typeText: String? get() = typeTextProvider?.invoke() ?: typeTextStatic - override fun build(): PolySymbolCodeCompletionItem = PolySymbolCodeCompletionItemImpl( name, offset, completeAfterInsert, completeAfterChars, displayName, symbol, priority, proximity, - apiStatus, aliases, icon, typeTextStatic, typeTextProvider, tailText, caseSensitive, insertHandler, stopSequencePatternEvaluation) + apiStatus, aliases, icon, typeText, typeTextGreyed, + tailText, tailTextGreyed, caseSensitive, asyncCustomizers, insertHandler, stopSequencePatternEvaluation) override fun displayName(value: String?): PolySymbolCodeCompletionItemBuilder { displayName = value @@ -270,12 +293,13 @@ internal data class PolySymbolCodeCompletionItemImpl( } override fun typeText(value: String?): PolySymbolCodeCompletionItemBuilder { - typeTextStatic = value + typeText = value return this } - override fun typeText(provider: () -> String?): PolySymbolCodeCompletionItemBuilder { - typeTextProvider = provider + override fun typeText(value: String?, greyed: Boolean): PolySymbolCodeCompletionItemBuilder { + typeText = value + typeTextGreyed = greyed return this } @@ -284,11 +308,22 @@ internal data class PolySymbolCodeCompletionItemImpl( return this } + override fun tailText(value: String?, greyed: Boolean): PolySymbolCodeCompletionItemBuilder { + tailText = value + tailTextGreyed = greyed + return this + } + override fun caseSensitive(value: Boolean): PolySymbolCodeCompletionItemBuilder { caseSensitive = value return this } + override fun asyncCustomizer(value: PolySymbolCodeCompletionItem.() -> PolySymbolCodeCompletionItem): PolySymbolCodeCompletionItemBuilder { + asyncCustomizers.add(value) + return this + } + override fun completeAfterInsert(value: Boolean): PolySymbolCodeCompletionItemBuilder { completeAfterInsert = value return this diff --git a/xml/xml-analysis-impl/src/com/intellij/polySymbols/html/HtmlCodeCompletionItemCustomizer.kt b/xml/xml-analysis-impl/src/com/intellij/polySymbols/html/HtmlCodeCompletionItemCustomizer.kt index 924e6800ea2c..6fa501077567 100644 --- a/xml/xml-analysis-impl/src/com/intellij/polySymbols/html/HtmlCodeCompletionItemCustomizer.kt +++ b/xml/xml-analysis-impl/src/com/intellij/polySymbols/html/HtmlCodeCompletionItemCustomizer.kt @@ -19,16 +19,18 @@ class HtmlCodeCompletionItemCustomizer : PolySymbolCodeCompletionItemCustomizer location: PsiElement, ): PolySymbolCodeCompletionItem = when (kind) { - HTML_ELEMENTS -> item.withTypeText { - item.symbol - ?.getDocumentationTarget(null) - ?.asSafely() - ?.documentation - ?.library - ?.let { - val atIndex = it.lastIndexOf('@') - if (atIndex > 0) it.substring(0, atIndex) else it - } + HTML_ELEMENTS -> item.withAsyncCustomizer { + withTypeText( + item.symbol + ?.getDocumentationTarget(null) + ?.asSafely() + ?.documentation + ?.library + ?.let { + val atIndex = it.lastIndexOf('@') + if (atIndex > 0) it.substring(0, atIndex) else it + } + ) } HTML_ATTRIBUTES -> item // TODO - we can figure out the actual type with full match provided else -> item