Skip to content

Commit

Permalink
Refactoring & Fix highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
YiiGuxing committed Sep 27, 2018
1 parent 9d5c03b commit eed51f3
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.github.izhangzhihao.rainbow.brackets

import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.colors.EditorColorsScheme
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme
import java.awt.Color

private const val DEFAULT_SCHEME_NAME = "Default"
private const val DARCULA_SCHEME_NAME = "Darcula"

fun migrateRainbowColors() {
val settings = RainbowSettings.instance
if (settings.lightRoundBracketsColors.isNullOrEmpty()
|| settings.lightSquareBracketsColors.isNullOrEmpty()
|| settings.lightSquigglyBracketsColors.isNullOrEmpty()
|| settings.lightAngleBracketsColor.isNullOrEmpty()
|| settings.darkRoundBracketsColors.isNullOrEmpty()
|| settings.darkSquareBracketsColors.isNullOrEmpty()
|| settings.darkSquigglyBracketsColors.isNullOrEmpty()
|| settings.darkAngleBracketsColor.isNullOrEmpty()) {
return
}

val round = settings.lightRoundBracketsColors?.map(::color)
val square = settings.lightSquareBracketsColors?.map(::color)
val squiggly = settings.lightSquigglyBracketsColors?.map(::color)
val angle = settings.lightAngleBracketsColor?.map(::color)

val roundDark = settings.darkRoundBracketsColors?.map(::color)
val squareDark = settings.darkSquareBracketsColors?.map(::color)
val squigglyDark = settings.darkSquigglyBracketsColors?.map(::color)
val angleDark = settings.darkAngleBracketsColor?.map(::color)

val schemeGroup = EditorColorsManager.getInstance()
.allSchemes
.mapNotNull { scheme -> (scheme as? AbstractColorsScheme)?.takeUnless { it.isReadOnly } }
.groupBy { it.parentScheme?.name }

schemeGroup[DEFAULT_SCHEME_NAME]?.forEach { scheme ->
scheme.migrateFrom(round, square, squiggly, angle)
}
schemeGroup[DARCULA_SCHEME_NAME]?.forEach { scheme ->
scheme.migrateFrom(roundDark, squareDark, squigglyDark, angleDark)
}

settings.lightRoundBracketsColors = null
settings.lightSquareBracketsColors = null
settings.lightSquigglyBracketsColors = null
settings.lightAngleBracketsColor = null
settings.darkRoundBracketsColors = null
settings.darkSquareBracketsColors = null
settings.darkSquigglyBracketsColors = null
settings.darkAngleBracketsColor = null
}

private fun AbstractColorsScheme.migrateFrom(round: List<Color>?,
square: List<Color>?,
squiggly: List<Color>?,
angle: List<Color>?) {
val migrated = migrateFrom(RainbowHighlighter.NAME_ROUND_BRACKETS, round)
|| migrateFrom(RainbowHighlighter.NAME_SQUARE_BRACKETS, square)
|| migrateFrom(RainbowHighlighter.NAME_SQUIGGLY_BRACKETS, squiggly)
|| migrateFrom(RainbowHighlighter.NAME_ANGLE_BRACKETS, angle)

if (migrated) {
setSaveNeeded(true)
}
}

private fun EditorColorsScheme.migrateFrom(rainbowName: String, colors: List<Color>?): Boolean {
if (colors == null || colors.isEmpty()) {
return false
}

val keys = RainbowHighlighter.getRainbowAttributesKeys(rainbowName)
for (i in 0 until (minOf(keys.size, colors.size))) {
setAttributes(keys[i], RainbowHighlighter.createRainbowAttributes(colors[i]))
}

return true
}

private fun <T> Array<T>?.isNullOrEmpty() = this == null || isEmpty()

private fun color(hex: String) = Color(Integer.decode(hex))
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.colors.EditorColorsScheme
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.openapi.editor.colors.TextAttributesScheme
import com.intellij.openapi.editor.markup.EffectType
import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.psi.PsiElement
import com.intellij.ui.JBColor
import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.TestOnly
import java.awt.Color
import java.awt.Font

object RainbowHighlighter {

val DEFAULT_KOTLIN_LABEL_COLOR = JBColor(0x4a86e8, 0x467cda)

const val NAME_ROUND_BRACKETS = "Round Brackets"
const val NAME_SQUARE_BRACKETS = "Square Brackets"
const val NAME_SQUIGGLY_BRACKETS = "Squiggly Brackets"
Expand Down Expand Up @@ -135,4 +140,36 @@ object RainbowHighlighter {
.range(element)
.create()
}


private val KEY_HTML_CODE = TextAttributesKey.createTextAttributesKey("HTML_CODE")
private val KEY_KOTLIN_LABEL = TextAttributesKey.createTextAttributesKey("KOTLIN_LABEL")
private val KEY_MATCHED_BRACE_ATTRIBUTES =
TextAttributesKey.createTextAttributesKey("MATCHED_BRACE_ATTRIBUTES")


fun fixHighlighting() {
val globalScheme = EditorColorsManager.getInstance().globalScheme
globalScheme.setInherited(KEY_HTML_CODE, !settings.isRainbowifyHTMLInsideJS)

// kotlin label
val kotlinLabelColor = DEFAULT_KOTLIN_LABEL_COLOR.takeUnless { settings.isRainbowifyKotlinLabel }
val kotlinLabel = TextAttributes(kotlinLabelColor, null, null, EffectType.BOXED, Font.PLAIN)
globalScheme.setAttributes(KEY_KOTLIN_LABEL, kotlinLabel)

// matched brace
val matchedBraceAttributes = if (settings.isOverrideMatchedBraceAttributes) {
TextAttributes(null, JBColor(0x99ccbb, 0x3b514d), null, EffectType.BOXED, Font.BOLD)
} else {
val isDark = UIUtil.isUnderDarcula()
val foregroundColor = if (isDark) Color(0xffef28) else null
val fontType = if (isDark) Font.BOLD else Font.PLAIN
TextAttributes(foregroundColor, JBColor(0x99ccff, 0x3b514d), null, EffectType.BOXED, fontType)
}
globalScheme.setAttributes(KEY_MATCHED_BRACE_ATTRIBUTES, matchedBraceAttributes)
}

private fun EditorColorsScheme.setInherited(key: TextAttributesKey, inherited: Boolean) {
setAttributes(key, if (inherited) TextAttributes.USE_INHERITED_MARKER else TextAttributes())
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.izhangzhihao.rainbow.brackets.annotator

import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
import com.intellij.lang.annotation.AnnotationHolder
Expand All @@ -9,7 +10,6 @@ import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.ui.JBColor
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import java.awt.Font
Expand Down Expand Up @@ -66,14 +66,11 @@ class KotlinLabelAnnotator : Annotator {
}

refElement
.let { RainbowInfo.RAINBOW_INFO_KEY[it]?.color ?: DEFAULT_LABEL_COLOR }
.let { RainbowInfo.RAINBOW_INFO_KEY[it]?.color ?: RainbowHighlighter.DEFAULT_KOTLIN_LABEL_COLOR }
.let {
holder.createInfoAnnotation(target, null)
.enforcedTextAttributes = TextAttributes(it, null, null, EffectType.BOXED, Font.PLAIN)
}
}

companion object {
private val DEFAULT_LABEL_COLOR = JBColor(0x4a86e8, 0x467cda)
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
package com.github.izhangzhihao.rainbow.brackets.component

import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
import com.github.izhangzhihao.rainbow.brackets.migrateRainbowColors
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ApplicationComponent
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.colors.EditorColorsScheme
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme
import com.intellij.openapi.editor.colors.impl.EditorColorsManagerImpl
import com.intellij.openapi.editor.markup.EffectType
import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.openapi.extensions.PluginId
import com.intellij.ui.JBColor
import java.awt.Color
import java.awt.Font

class RainbowComponent : ApplicationComponent {

Expand All @@ -26,108 +17,19 @@ class RainbowComponent : ApplicationComponent {
val settings = RainbowSettings.instance
updated = getPlugin()?.version != settings.version
if (updated) {
onUpgrade()
migrateRainbowColors()
settings.version = getPlugin()!!.version
}

val globalScheme = EditorColorsManager.getInstance().globalScheme
if (settings.isRainbowifyHTMLInsideJS) {
globalScheme.setAttributes(KEY_HTML_CODE, TextAttributes())
}
if (settings.isRainbowifyKotlinFunctionLiteralBracesAndArrow) {
globalScheme.setAttributes(KEY_KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW,
// Default Attributes
TextAttributes(null, null, null, EffectType.BOXED, Font.BOLD))
}
if (settings.isRainbowifyKotlinLabel) {
globalScheme.setAttributes(KEY_KOTLIN_LABEL,
TextAttributes(null, null, null, EffectType.BOXED, Font.PLAIN))
}
if (settings.isOverrideMatchedBraceAttributes) {
globalScheme.setAttributes(KEY_MATCHED_BRACE_ATTRIBUTES,
TextAttributes(null, JBColor(0x99ccbb, 0x3b514d), null, EffectType.BOXED, Font.BOLD))
}
}

private fun onUpgrade() {
val settings = RainbowSettings.instance

val round = settings.lightRoundBracketsColors?.map(::color)
val square = settings.lightSquareBracketsColors?.map(::color)
val squiggly = settings.lightSquigglyBracketsColors?.map(::color)
val angle = settings.lightAngleBracketsColor?.map(::color)

val roundDark = settings.darkRoundBracketsColors?.map(::color)
val squareDark = settings.darkSquareBracketsColors?.map(::color)
val squigglyDark = settings.darkSquigglyBracketsColors?.map(::color)
val angleDark = settings.darkAngleBracketsColor?.map(::color)

val colorsManager = EditorColorsManager.getInstance() as EditorColorsManagerImpl
val schemeGroup = colorsManager.allSchemes
.mapNotNull { scheme -> (scheme as? AbstractColorsScheme)?.takeUnless { it.isReadOnly } }
.groupBy { it.parentScheme?.name }

schemeGroup[DEFAULT_SCHEME_NAME]?.forEach { scheme ->
scheme.migrateFrom(round, square, squiggly, angle)
}
schemeGroup[DARCULA_SCHEME_NAME]?.forEach { scheme ->
scheme.migrateFrom(roundDark, squareDark, squigglyDark, angleDark)
}

settings.lightRoundBracketsColors = null
settings.lightSquareBracketsColors = null
settings.lightSquigglyBracketsColors = null
settings.lightAngleBracketsColor = null
settings.darkRoundBracketsColors = null
settings.darkSquareBracketsColors = null
settings.darkSquigglyBracketsColors = null
settings.darkAngleBracketsColor = null
}

private fun AbstractColorsScheme.migrateFrom(round: List<Color>?,
square: List<Color>?,
squiggly: List<Color>?,
angle: List<Color>?) {
val migrated = migrateFrom(RainbowHighlighter.NAME_ROUND_BRACKETS, round)
|| migrateFrom(RainbowHighlighter.NAME_SQUARE_BRACKETS, square)
|| migrateFrom(RainbowHighlighter.NAME_SQUIGGLY_BRACKETS, squiggly)
|| migrateFrom(RainbowHighlighter.NAME_ANGLE_BRACKETS, angle)

if (migrated) {
setSaveNeeded(true)
}
}

private fun EditorColorsScheme.migrateFrom(rainbowName: String, colors: List<Color>?): Boolean {
if (colors == null || colors.isEmpty()) {
return false
}

val keys = RainbowHighlighter.getRainbowAttributesKeys(rainbowName)
for (i in 0 until (minOf(keys.size, colors.size))) {
setAttributes(keys[i], RainbowHighlighter.createRainbowAttributes(colors[i]))
}

return true
RainbowHighlighter.fixHighlighting()
}

companion object {
private const val DEFAULT_SCHEME_NAME = "Default"
private const val DARCULA_SCHEME_NAME = "Darcula"

private val KEY_HTML_CODE = TextAttributesKey.createTextAttributesKey("HTML_CODE")
private val KEY_KOTLIN_LABEL = TextAttributesKey.createTextAttributesKey("KOTLIN_LABEL")
private val KEY_MATCHED_BRACE_ATTRIBUTES =
TextAttributesKey.createTextAttributesKey("MATCHED_BRACE_ATTRIBUTES")
private val KEY_KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW =
TextAttributesKey.createTextAttributesKey("KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW")

val instance: RainbowComponent
get() = ApplicationManager.getApplication().getComponent(RainbowComponent::class.java)

private fun getPlugin(): IdeaPluginDescriptor? = PluginManager.getPlugin(
PluginId.getId("izhangzhihao.rainbow.brackets"))

private fun color(hex: String) = Color(Integer.decode(hex))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class RainbowSettings : PersistentStateComponent<RainbowSettings> {
var isDoNOTRainbowifyBracketsWithoutContent = false
var version = "Unknown"
var isRainbowifyHTMLInsideJS = true
var isRainbowifyKotlinFunctionLiteralBracesAndArrow = true
var isRainbowifyKotlinLabel = true
var isOverrideMatchedBraceAttributes = true

Expand Down

0 comments on commit eed51f3

Please sign in to comment.