diff --git a/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureAnnotator.kt b/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureAnnotator.kt index c3322a1..929f8cb 100644 --- a/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureAnnotator.kt +++ b/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureAnnotator.kt @@ -67,10 +67,6 @@ class ClojureAnnotator : Annotator { } } - private fun isNamespaced(element: ClKeyword) = - (element.text?.contains("/") == true) && - (element.parentOfType(false) == null) - private fun isNsReaderMacro(element: PsiElement) = (element.prevSibling != null) && (element.prevSibling.text == "#:") && @@ -81,4 +77,11 @@ class ClojureAnnotator : Annotator { (element.nextSibling is LeafPsiElement) && ((element.nextSibling as LeafPsiElement).elementType.toString() == "ns separator") && (element.parentOfType(false) == null) + + companion object { + fun isNamespaced(element: ClKeyword) = + (element.text?.contains("/") == true) && + (element.parentOfType(false) == null) + } + } diff --git a/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureColorsAndFontPageEx.kt b/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureColorsAndFontPageEx.kt index 42775ea..9acdb03 100644 --- a/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureColorsAndFontPageEx.kt +++ b/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/ClojureColorsAndFontPageEx.kt @@ -1,16 +1,19 @@ package com.github.brcosta.cljstuffplugin.extensions +import com.intellij.codeHighlighting.RainbowHighlighter +import com.intellij.lang.Language import com.intellij.openapi.editor.colors.TextAttributesKey import com.intellij.openapi.fileTypes.SyntaxHighlighter import com.intellij.openapi.options.colors.AttributesDescriptor import com.intellij.openapi.options.colors.ColorDescriptor -import com.intellij.openapi.options.colors.ColorSettingsPage +import com.intellij.openapi.options.colors.RainbowColorSettingsPage import cursive.ClojureIcons +import cursive.ClojureLanguage import cursive.highlighter.ClojureSyntaxHighlighter import javax.swing.Icon @Suppress("unused") -class ClojureColorsAndFontsPageEx : ColorSettingsPage { +class ClojureColorsAndFontsPageEx : RainbowColorSettingsPage { override fun getDisplayName(): String { return "Clojure Extras" @@ -37,18 +40,28 @@ class ClojureColorsAndFontsPageEx : ColorSettingsPage { } override fun getAdditionalHighlightingTagToDescriptorMap(): Map { - val map: MutableMap = mutableMapOf() + val map = RainbowHighlighter.createRainbowHLM() map["keyword-namespace"] = KEYWORD_NAMESPACE map["symbol-namespace"] = SYMBOL_NAMESPACE map["head-symbol-namespace"] = HEAD_SYMBOL_NAMESPACE return map } + override fun isRainbowType(type: TextAttributesKey?): Boolean { + return type == SEMANTIC_HIGHLIGHTING + } + + override fun getLanguage(): Language? { + return ClojureLanguage.getInstance() + } + companion object { private val ATTRS: Array val KEYWORD_NAMESPACE = TextAttributesKey.createTextAttributesKey("Keyword Namespace") val SYMBOL_NAMESPACE = TextAttributesKey.createTextAttributesKey("Symbol Namespace") val HEAD_SYMBOL_NAMESPACE = TextAttributesKey.createTextAttributesKey("Head Symbol Namespace") + val SEMANTIC_HIGHLIGHTING = TextAttributesKey.createTextAttributesKey("Semantic Highlighting") + init { ATTRS = arrayOf( AttributesDescriptor("Keyword Namespace", KEYWORD_NAMESPACE), diff --git a/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/codeInsight/daemon/ClojureRainbowVisitor.kt b/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/codeInsight/daemon/ClojureRainbowVisitor.kt new file mode 100644 index 0000000..b64a2dc --- /dev/null +++ b/src/main/kotlin/com/github/brcosta/cljstuffplugin/extensions/codeInsight/daemon/ClojureRainbowVisitor.kt @@ -0,0 +1,76 @@ +package com.github.brcosta.cljstuffplugin.extensions.codeInsight.daemon + +import com.github.brcosta.cljstuffplugin.extensions.ClojureAnnotator.Companion.isNamespaced +import com.github.brcosta.cljstuffplugin.extensions.ClojureColorsAndFontsPageEx.Companion.SEMANTIC_HIGHLIGHTING +import com.intellij.codeInsight.daemon.RainbowVisitor +import com.intellij.codeInsight.daemon.UsedColors +import com.intellij.codeInsight.daemon.impl.HighlightInfo +import com.intellij.codeInsight.daemon.impl.HighlightVisitor +import com.intellij.openapi.util.UserDataHolderEx +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import cursive.psi.api.ClKeyword +import cursive.psi.api.ClojureFile +import cursive.psi.api.symbols.ClSymbol + +/** + * Enables semantic highlighting for all symbols and keywords. Namespaces are treated as separate highlighted elements. + */ +class ClojureRainbowVisitor : RainbowVisitor() { + override fun suitableForFile(file: PsiFile): Boolean { + return file is ClojureFile + } + + override fun visit(element: PsiElement) { + val maybeName = when (element) { + is ClSymbol -> element.name + is ClKeyword -> element.name + else -> null + } + maybeName?.let { elementName -> + element.context?.let { context -> + fun separateNsHighlighting(keyword: ClKeyword): List { + fun rangedInfo(name: String, start: Int, end: Int): HighlightInfo { + val color = + UsedColors.getOrAddColorIndex((context as UserDataHolderEx), name, highlighter.colorsCount) + return highlighter.getInfo(color, start, end, SEMANTIC_HIGHLIGHTING) + } + + val start = keyword.textRange.startOffset + val nsEnd = start + keyword.text.indexOf('/') + return listOf( + rangedInfo( + keyword.namespace, + start, + nsEnd, + ), + rangedInfo( + elementName, + nsEnd, + keyword.textRange.endOffset, + ) + ) + } + + if (element is ClKeyword && isNamespaced(element)) + separateNsHighlighting(element).forEach(::addInfo) + else + // separate ns highlighting for symbols works by default + addInfo( + getInfo( + context, + element, + elementName, + SEMANTIC_HIGHLIGHTING + ) + ) + + } + } + } + + override fun clone(): HighlightVisitor { + return ClojureRainbowVisitor() + } + +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 3e91f80..4efc58d 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,6 +19,7 @@ +