Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "com.github.lppedd"
version = "0.2.2"
version = "0.2.3"

repositories {
maven("https://dl.bintray.com/kotlin/kotlin-eap")
Expand Down
3 changes: 2 additions & 1 deletion plugin-description.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<p>
This plugin provides code style customization for
<strong>infix</strong> and <strong>operator</strong> (math and keyword) functions.
<strong>infix</strong> and <strong>operator</strong> (math and keyword) functions
and more keywords customization.
</p>
<br/>
<p>
Expand Down
179 changes: 144 additions & 35 deletions src/main/kotlin/com/github/lppedd/kotlin/KotlinAnnotator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,168 @@ import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors
import org.jetbrains.kotlin.lexer.KtKeywordToken
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtOperationReferenceExpression

internal val KOTLIN_INFIX_FUN: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_INFIX_FUN",
KotlinHighlightingColors.FUNCTION_CALL
)
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_INFIX_FUN",
KotlinHighlightingColors.FUNCTION_CALL
)

internal val KOTLIN_KEYWORD_OPERATOR_FUN: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_KEYWORD_OPERATOR_FUN",
KotlinHighlightingColors.KEYWORD
)
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_KEYWORD_OPERATOR_FUN",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_MATH_OPERATOR_FUN: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_MATH_OPERATOR_FUN",
KotlinHighlightingColors.OPERATOR_SIGN
)
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_MATH_OPERATOR_FUN",
KotlinHighlightingColors.OPERATOR_SIGN
)

internal val KOTLIN_MODIFIER_OVERRIDE: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_MODIFIER_OVERRIDE",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_MODIFIER: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_MODIFIER",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_SEALED_OPEN: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_SEALED_OPEN",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_COMPANION: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_COMPANION",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_DATA: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_DATA",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_OPERATOR_INFIX: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_OPERATOR_INFIX",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_THIS_SUPER: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_THIS_SUPER",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_NULL: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_NULL",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_TRUE_FALSE: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_TRUE_FALSE",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_ABSTRACT: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_ABSTRACT",
KotlinHighlightingColors.KEYWORD
)

internal val KOTLIN_SUSPEND: TextAttributesKey =
TextAttributesKey.createTextAttributesKey(
"CUSTOM_KOTLIN_SUSPEND",
KotlinHighlightingColors.KEYWORD
)

/**
* @author Edoardo Luppi
*/
private class KotlinAnnotator : Annotator {
private val globalScheme = EditorColorsManager.getInstance().globalScheme
private val globalScheme = EditorColorsManager.getInstance().globalScheme

override fun annotate(element: PsiElement, annotationHolder: AnnotationHolder) {
if (element is KtOperationReferenceExpression) {
getTextAttributes(element)?.let {
annotationHolder.setTextAttributes(element, it)
}
} else if (element is LeafPsiElement) {
getTextAttributes(element)?.let {
annotationHolder.setTextAttributes(element, it)
}
}
}

override fun annotate(element: PsiElement, annotationHolder: AnnotationHolder) {
if (element is KtOperationReferenceExpression) {
getTextAttributes(element)?.let {
annotationHolder.setTextAttributes(element, it)
}
private fun getTextAttributes(expr: KtOperationReferenceExpression): TextAttributes? {
val operationSignTokenType = expr.operationSignTokenType
return when {
operationSignTokenType is KtKeywordToken -> KOTLIN_KEYWORD_OPERATOR_FUN.getAttributes()
operationSignTokenType is KtSingleValueToken -> KOTLIN_MATH_OPERATOR_FUN.getAttributes()
!expr.isConventionOperator() -> KOTLIN_INFIX_FUN.getAttributes()
else -> null
}
}
}

private fun getTextAttributes(expr: KtOperationReferenceExpression): TextAttributes? {
val operationSignTokenType = expr.operationSignTokenType
return when {
operationSignTokenType is KtKeywordToken -> KOTLIN_KEYWORD_OPERATOR_FUN.getAttributes()
operationSignTokenType is KtSingleValueToken -> KOTLIN_MATH_OPERATOR_FUN.getAttributes()
!expr.isConventionOperator() -> KOTLIN_INFIX_FUN.getAttributes()
else -> null

private fun getTextAttributes(element: LeafPsiElement): TextAttributes? {
return when (element.elementType) {
KtTokens.PUBLIC_KEYWORD,
KtTokens.PRIVATE_KEYWORD,
KtTokens.PROTECTED_KEYWORD,
KtTokens.INNER_KEYWORD,
KtTokens.INTERNAL_KEYWORD -> KOTLIN_MODIFIER.getAttributes()

KtTokens.OVERRIDE_KEYWORD -> KOTLIN_MODIFIER_OVERRIDE.getAttributes()

KtTokens.SEALED_KEYWORD,
KtTokens.OPEN_KEYWORD -> KOTLIN_SEALED_OPEN.getAttributes()

KtTokens.OBJECT_KEYWORD,
KtTokens.COMPANION_KEYWORD -> KOTLIN_COMPANION.getAttributes()

KtTokens.DATA_KEYWORD -> KOTLIN_DATA.getAttributes()

KtTokens.OPERATOR_KEYWORD,
KtTokens.INFIX_KEYWORD -> KOTLIN_OPERATOR_INFIX.getAttributes()

KtTokens.THIS_KEYWORD,
KtTokens.SUPER_KEYWORD -> KOTLIN_THIS_SUPER.getAttributes()

KtTokens.NULL_KEYWORD -> KOTLIN_NULL.getAttributes()

KtTokens.TRUE_KEYWORD,
KtTokens.FALSE_KEYWORD -> KOTLIN_TRUE_FALSE.getAttributes()

KtTokens.ABSTRACT_KEYWORD -> KOTLIN_ABSTRACT.getAttributes()

KtTokens.SUSPEND_KEYWORD -> KOTLIN_SUSPEND.getAttributes()

else -> null
}
}
}

private fun AnnotationHolder.setTextAttributes(
element: PsiElement,
textAttributes: TextAttributes) {
createInfoAnnotation(element, null).enforcedTextAttributes = textAttributes
}
private fun AnnotationHolder.setTextAttributes(
element: PsiElement,
textAttributes: TextAttributes) {
createInfoAnnotation(element, null).enforcedTextAttributes = textAttributes
}

private fun TextAttributesKey.getAttributes(): TextAttributes =
globalScheme.getAttributes(this)
private fun TextAttributesKey.getAttributes(): TextAttributes =
globalScheme.getAttributes(this)
}
100 changes: 88 additions & 12 deletions src/main/kotlin/com/github/lppedd/kotlin/KotlinColorSettingsPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,104 @@ private class KotlinColorSettingsPage : ColorSettingsPage {

override fun getAttributeDescriptors(): Array<AttributesDescriptor> =
arrayOf(
AttributesDescriptor("Infix function call", KOTLIN_INFIX_FUN),
AttributesDescriptor("Keyword operator function call", KOTLIN_KEYWORD_OPERATOR_FUN),
AttributesDescriptor("Math operator function call", KOTLIN_MATH_OPERATOR_FUN),
AttributesDescriptor("Operation//Infix function call", KOTLIN_INFIX_FUN),
AttributesDescriptor("Operation//Keyword operator function call", KOTLIN_KEYWORD_OPERATOR_FUN),
AttributesDescriptor("Operation//Math operator function call", KOTLIN_MATH_OPERATOR_FUN),

AttributesDescriptor("Keywords//override", KOTLIN_MODIFIER_OVERRIDE),
AttributesDescriptor("Keywords//public private protected internal inner", KOTLIN_MODIFIER),
AttributesDescriptor("Keywords//sealed open", KOTLIN_SEALED_OPEN),
AttributesDescriptor("Keywords//companion", KOTLIN_COMPANION),
AttributesDescriptor("Keywords//data", KOTLIN_DATA),
AttributesDescriptor("Keywords//operator infix", KOTLIN_OPERATOR_INFIX),
AttributesDescriptor("Keywords//this super", KOTLIN_THIS_SUPER),
AttributesDescriptor("Keywords//null", KOTLIN_NULL),
AttributesDescriptor("Keywords//true false", KOTLIN_TRUE_FALSE),
AttributesDescriptor("Keywords//abstract", KOTLIN_ABSTRACT),
AttributesDescriptor("Keywords//suspend", KOTLIN_SUSPEND),
)

override fun getAdditionalHighlightingTagToDescriptorMap(): Map<String, TextAttributesKey> =
mapOf(
"k-infix" to KOTLIN_INFIX_FUN,
"k-kw-operator" to KOTLIN_KEYWORD_OPERATOR_FUN,
"k-math-operator" to KOTLIN_MATH_OPERATOR_FUN,
"kt-infix" to KOTLIN_INFIX_FUN,
"kt-operator" to KOTLIN_KEYWORD_OPERATOR_FUN,
"kt-math-operator" to KOTLIN_MATH_OPERATOR_FUN,

"kt-kw-override" to KOTLIN_MODIFIER_OVERRIDE,
"kt-kw-modifier" to KOTLIN_MODIFIER,
"kt-kw-sealed" to KOTLIN_SEALED_OPEN,
"kt-kw-open" to KOTLIN_SEALED_OPEN,
"kt-kw-companion" to KOTLIN_COMPANION,
"kt-kw-data" to KOTLIN_DATA,
"kt-kw-operator" to KOTLIN_OPERATOR_INFIX,
"kt-kw-infix" to KOTLIN_OPERATOR_INFIX,
"kt-kw-this" to KOTLIN_THIS_SUPER,
"kt-kw-super" to KOTLIN_THIS_SUPER,
"kt-kw-null" to KOTLIN_NULL,
"kt-kw-true" to KOTLIN_TRUE_FALSE,
"kt-kw-false" to KOTLIN_TRUE_FALSE,
"kt-kw-abstract" to KOTLIN_ABSTRACT,
"kt-kw-suspend" to KOTLIN_SUSPEND,
)

override fun getDemoText(): String = """
|fun myFunction(myValue: String, myValues: List<String>) {
| if (myValue <k-infix>owns</k-infix> 'c') { }
| if (myValue <k-kw-operator>!in</k-kw-operator> myValues) { }
| if (myValue <k-math-operator>></k-math-operator> myValues.first()) { }
|import java.util.*
|
|package myPackage.hello
|
|<kt-kw-open>open</kt-kw-open> class MyClass {
| <kt-kw-modifier>private</kt-kw-modifier> val fooBar = "";
|
| <kt-kw-modifier>protected</kt-kw-modifier> <kt-kw-open>open</kt-kw-open> fun foo(): Unit? {
| val values = listOf(<kt-kw-true>true</kt-kw-true>, <kt-kw-null>null</kt-kw-null>, <kt-kw-false>false</kt-kw-false>)
| println(values)
| return <kt-kw-null>null</kt-kw-null>
| }
|
| <kt-kw-modifier>internal</kt-kw-modifier> fun bar() {
| return Unit
| }
|}
|
|<kt-kw-sealed>sealed</kt-kw-sealed> class MySealedClass : MyClass() {
| <kt-kw-override>override</kt-kw-override> fun foo(): Unit? {
| println("override")
| <kt-kw-super>super</kt-kw-super>.foo()
| return null
| }
|
| <kt-kw-companion>companion</kt-kw-companion> object {
| fun create(): MyClass {
| return MyClass()
| }
| }
|}
|
|infix fun String.owns(char: Char): Boolean = contains(char)
|<kt-kw-data>data</kt-kw-data> class MyDataClass(val num: Int) {
| <kt-kw-modifier>public</kt-kw-modifier> <kt-kw-operator>operator</kt-kw-operator> <kt-kw-infix>infix</kt-kw-infix> fun plus(to: Int) {
| return <kt-kw-this>this</kt-kw-this> + to
| }
|}
|
|<kt-kw-override>override</kt-kw-override> fun myFunction(myValue: String, myValues: List<String>) {
| if (myValue <kt-infix>owns</kt-infix> 'c') { }
| if (myValue <kt-operator>!in</kt-operator> myValues) { }
| if (myValue <kt-math-operator>></kt-math-operator> myValues.first()) { }
|}
|
|<kt-kw-abstract>abstract</kt-kw-abstract> class AbstractClass {
| abstract val text: Int
|}
|
|<kt-kw-modifier>inner</kt-kw-modifier> class InnerClass {}
|
|<kt-kw-suspend>suspend</kt-kw-suspend> fun suspendCall() = suspendFun()
|
|<kt-kw-suspend>suspend</kt-kw-suspend> fun suspendFun() {}
|
|<kt-kw-infix>infix</kt-kw-infix> fun String.owns(char: Char): Boolean = contains(char)
""".trimMargin()

override fun getColorDescriptors(): Array<ColorDescriptor> =
ColorDescriptor.EMPTY_ARRAY
}
}