User: rednesto Date: 01 Aug 24 14:45 Revision: 1801be074a48212f6a2c201299deb2a103737be2 Summary: Provide documentation in mods.toml key completion TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=9530&personal=false Index: src/main/kotlin/toml/TomlSchema.kt =================================================================== --- src/main/kotlin/toml/TomlSchema.kt (revision 23821336cf07f577b4058eb057250b806adb2bc5) +++ src/main/kotlin/toml/TomlSchema.kt (revision 1801be074a48212f6a2c201299deb2a103737be2) @@ -42,9 +42,15 @@ fun topLevelKeys(isArray: Boolean): Set = tables.filter { it.isArray == isArray }.mapTo(mutableSetOf()) { it.name } + fun topLevelEntries(isArray: Boolean): Set = + tables.filter { it.isArray == isArray }.flatMapTo(mutableSetOf()) { it.entries } + fun keysForTable(tableName: String): Set = tableSchema(tableName)?.entries?.mapTo(mutableSetOf()) { it.key }.orEmpty() + fun entriesForTable(tableName: String): Set = + tableSchema(tableName)?.entries.orEmpty() + fun tableEntry(tableName: String, key: String): TomlSchemaEntry? = tableSchema(tableName)?.entries?.find { it.key == key } Index: src/main/kotlin/toml/platform/forge/ModsTomlDocumentationProvider.kt =================================================================== --- src/main/kotlin/toml/platform/forge/ModsTomlDocumentationProvider.kt (revision 23821336cf07f577b4058eb057250b806adb2bc5) +++ src/main/kotlin/toml/platform/forge/ModsTomlDocumentationProvider.kt (revision 1801be074a48212f6a2c201299deb2a103737be2) @@ -21,12 +21,19 @@ package com.demonwav.mcdev.toml.platform.forge import com.demonwav.mcdev.platform.forge.util.ForgeConstants +import com.demonwav.mcdev.toml.TomlSchemaEntry import com.intellij.lang.documentation.DocumentationMarkup import com.intellij.lang.documentation.DocumentationProvider +import com.intellij.navigation.ItemPresentation import com.intellij.openapi.editor.Editor +import com.intellij.openapi.util.NlsSafe import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile +import com.intellij.psi.PsiManager +import com.intellij.psi.impl.FakePsiElement +import com.intellij.psi.impl.source.DummyHolderFactory import com.intellij.psi.util.parentOfType +import javax.swing.Icon import org.toml.lang.psi.TomlHeaderOwner import org.toml.lang.psi.TomlKey import org.toml.lang.psi.TomlKeySegment @@ -50,7 +57,28 @@ ?: contextElement?.parentOfType() } + override fun getDocumentationElementForLookupItem( + psiManager: PsiManager, + entry: Any?, + element: PsiElement? + ): PsiElement? { + if (entry !is TomlSchemaEntry) { + return null + } + + val description = entry.description.joinToString("\n") + return if (description.isNotBlank()) { + TomlSchemaKeyElement(entry.key, description, psiManager) + } else { + null + } + } + override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? { + if (element is TomlSchemaKeyElement) { + return element.description + } + if (element !is TomlKeySegment || !isModsToml(originalElement)) { return null } @@ -80,4 +108,23 @@ private fun isModsToml(element: PsiElement?): Boolean = element?.containingFile?.virtualFile?.name == ForgeConstants.MODS_TOML + + private class TomlSchemaKeyElement( + val key: String, + val description: String, + val psiManager: PsiManager + ) : FakePsiElement() { + + private val dummyHolder = DummyHolderFactory.createHolder(psiManager, null) + + override fun getParent(): PsiElement? = dummyHolder + + override fun getManager(): PsiManager? = psiManager + + override fun getPresentation(): ItemPresentation? = object : ItemPresentation { + override fun getPresentableText(): @NlsSafe String? = key + + override fun getIcon(unused: Boolean): Icon? = null -} + } + } +} Index: src/main/kotlin/toml/platform/forge/completion/ModsTomlCompletionContributor.kt =================================================================== --- src/main/kotlin/toml/platform/forge/completion/ModsTomlCompletionContributor.kt (revision 23821336cf07f577b4058eb057250b806adb2bc5) +++ src/main/kotlin/toml/platform/forge/completion/ModsTomlCompletionContributor.kt (revision 1801be074a48212f6a2c201299deb2a103737be2) @@ -21,6 +21,7 @@ package com.demonwav.mcdev.toml.platform.forge.completion import com.demonwav.mcdev.platform.forge.util.ForgeConstants +import com.demonwav.mcdev.toml.TomlSchemaEntry import com.demonwav.mcdev.toml.TomlStringValueInsertionHandler import com.demonwav.mcdev.toml.inModsTomlKey import com.demonwav.mcdev.toml.inModsTomlValueWithKey @@ -88,7 +89,7 @@ val keySegment = parameters.position.parent as? TomlKeySegment ?: return val key = keySegment.parent as? TomlKey ?: return val table = key.parentOfType() - val variants = when (val parent = key.parent) { + val variants: Collection = when (val parent = key.parent) { is TomlTableHeader -> { if (key != parent.key?.segments?.firstOrNull()) { return @@ -98,22 +99,26 @@ is TomlTable -> false else -> return } - schema.topLevelKeys(isArray) - table.entries.mapTo(HashSet()) { it.key.text } + val existingKeys = table.entries.mapTo(HashSet()) { it.key.text } + schema.topLevelEntries(isArray).filter { it.key !in existingKeys } } is TomlKeyValue -> when (table) { null -> { - schema.topLevelEntries.map { it.key } - + val existingKeys = key.containingFile.children.filterIsInstance().mapTo(HashSet()) { it.key.text } + schema.topLevelEntries.filter { it.key !in existingKeys } } is TomlHeaderOwner -> { val tableName = table.header.key?.segments?.firstOrNull()?.text ?: return - schema.keysForTable(tableName) - table.entries.mapTo(HashSet()) { it.key.text } + val existingKeys = table.entries.mapTo(HashSet()) { it.key.text } + schema.entriesForTable(tableName).filter { it.key !in existingKeys } } else -> return } else -> return } - result.addAllElements(variants.map(LookupElementBuilder::create)) + + result.addAllElements(variants.map { entry -> LookupElementBuilder.create(entry, entry.key) }) } }