From 94602bd8f9281bf768ef8cbbbdbb8eb2877ff233 Mon Sep 17 00:00:00 2001 From: synopss <synopss@outlook.com> Date: Fri, 12 May 2023 18:06:12 +0200 Subject: [PATCH] Add line background colors Closes #14 --- .../inspectionlens/editor/EditorLens.kt | 14 ++++- .../editor/EditorLensLineBackground.kt | 53 +++++++++++++++++++ .../editor/EditorLensManager.kt | 3 ++ .../inspectionlens/editor/LensRenderer.kt | 2 +- .../inspectionlens/editor/LensSeverity.kt | 23 ++++---- .../editor/LensSeverityTextAttributes.kt | 12 ++++- 6 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensLineBackground.kt diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLens.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLens.kt index 433dd35..485791c 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLens.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLens.kt @@ -3,7 +3,7 @@ package com.chylex.intellij.inspectionlens.editor import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.openapi.editor.Editor -internal class EditorLens private constructor(private var inlay: EditorLensInlay) { +internal class EditorLens private constructor(private var inlay: EditorLensInlay, private var lineBackground: EditorLensLineBackground) { fun update(info: HighlightInfo): Boolean { val editor = inlay.editor @@ -11,16 +11,26 @@ internal class EditorLens private constructor(private var inlay: EditorLensInlay inlay = EditorLensInlay.show(editor, info) ?: return false } + if (lineBackground.shouldRecreate(info)) { + lineBackground.hide(editor) + lineBackground = EditorLensLineBackground.show(editor, info) + } + return true } fun hide() { + val editor = inlay.editor + inlay.hide() + lineBackground.hide(editor) } companion object { fun show(editor: Editor, info: HighlightInfo): EditorLens? { - return EditorLensInlay.show(editor, info)?.let(::EditorLens) + val inlay = EditorLensInlay.show(editor, info) ?: return null + val lineBackground = EditorLensLineBackground.show(editor, info) + return EditorLens(inlay, lineBackground) } } } diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensLineBackground.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensLineBackground.kt new file mode 100644 index 0000000..7bb1857 --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensLineBackground.kt @@ -0,0 +1,53 @@ +package com.chylex.intellij.inspectionlens.editor + +import com.intellij.codeInsight.daemon.impl.HighlightInfo +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.markup.HighlighterLayer +import com.intellij.openapi.editor.markup.HighlighterTargetArea.LINES_IN_RANGE +import com.intellij.openapi.editor.markup.RangeHighlighter + +@JvmInline +internal value class EditorLensLineBackground(private val highlighter: RangeHighlighter) { + @Suppress("RedundantIf") + fun shouldRecreate(info: HighlightInfo): Boolean { + if (!highlighter.isValid) { + return true + } + + val severity = LensSeverity.from(info.severity) + + val currentTextAttributes = highlighter.getTextAttributes(null) + val newTextAttributes = severity.lineAttributes + if (currentTextAttributes !== newTextAttributes) { + return true + } + + val currentLayer = highlighter.layer + val newLayer = getHighlightLayer(severity) + if (currentLayer != newLayer) { + return true + } + + return false + } + + fun hide(editor: Editor) { + editor.markupModel.removeHighlighter(highlighter) + } + + companion object { + fun show(editor: Editor, info: HighlightInfo): EditorLensLineBackground { + val startOffset = info.actualStartOffset + val endOffset = info.actualEndOffset + + val severity = LensSeverity.from(info.severity) + val layer = getHighlightLayer(severity) + + return EditorLensLineBackground(editor.markupModel.addRangeHighlighter(startOffset, endOffset, layer, severity.lineAttributes, LINES_IN_RANGE)) + } + + private fun getHighlightLayer(severity: LensSeverity): Int { + return HighlighterLayer.CARET_ROW - 100 - severity.ordinal + } + } +} diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensManager.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensManager.kt index 99f48ef..1343fd2 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensManager.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensManager.kt @@ -71,6 +71,9 @@ class EditorLensManager private constructor(private val editor: Editor) { } } + /** + * Batch mode affects both inlays and highlighters used for line colors. + */ @Suppress("ConvertLambdaToReference") private inline fun executeInBatchMode(operations: Int, crossinline action: () -> Unit) { if (operations > 1000) { diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensRenderer.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensRenderer.kt index 2ae39a0..16d1630 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensRenderer.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensRenderer.kt @@ -30,7 +30,7 @@ class LensRenderer(info: HighlightInfo) : HintRenderer(null) { } override fun getTextAttributes(editor: Editor): TextAttributes { - return severity.colorAttributes + return severity.textAttributes } override fun useEditorFont(): Boolean { diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverity.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverity.kt index f144957..412c7c0 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverity.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverity.kt @@ -5,6 +5,7 @@ import com.chylex.intellij.inspectionlens.utils.DebouncingInvokeOnDispatchThread import com.intellij.lang.annotation.HighlightSeverity import com.intellij.spellchecker.SpellCheckerSeveritiesProvider import com.intellij.ui.ColorUtil +import com.intellij.ui.ColorUtil.toAlpha import com.intellij.ui.JBColor import java.awt.Color import java.awt.Font @@ -15,22 +16,26 @@ import java.util.Collections */ @Suppress("UseJBColor", "InspectionUsingGrayColors") enum class LensSeverity(baseColor: Color, lightThemeDarkening: Int, darkThemeBrightening: Int) { - ERROR (Color(158, 41, 39), lightThemeDarkening = 1, darkThemeBrightening = 4), - WARNING (Color(190, 145, 23), lightThemeDarkening = 4, darkThemeBrightening = 1), - WEAK_WARNING (Color(117, 109, 86), lightThemeDarkening = 3, darkThemeBrightening = 3), - SERVER_PROBLEM (Color(176, 97, 0), lightThemeDarkening = 4, darkThemeBrightening = 2), - GRAZIE (Color( 53, 146, 196), lightThemeDarkening = 2, darkThemeBrightening = 1), - TYPO (Color( 73, 156, 84), lightThemeDarkening = 3, darkThemeBrightening = 1), - OTHER (Color(128, 128, 128), lightThemeDarkening = 1, darkThemeBrightening = 2); + ERROR (Color(158, 41, 39), lightThemeDarkening = 2, darkThemeBrightening = 4), + WARNING (Color(190, 145, 23), lightThemeDarkening = 5, darkThemeBrightening = 1), + WEAK_WARNING (Color(117, 109, 86), lightThemeDarkening = 4, darkThemeBrightening = 4), + SERVER_PROBLEM (Color(176, 97, 0), lightThemeDarkening = 5, darkThemeBrightening = 2), + GRAZIE (Color( 53, 146, 196), lightThemeDarkening = 3, darkThemeBrightening = 1), + TYPO (Color( 73, 156, 84), lightThemeDarkening = 4, darkThemeBrightening = 1), + OTHER (Color(128, 128, 128), lightThemeDarkening = 2, darkThemeBrightening = 2); - val colorAttributes: LensSeverityTextAttributes + val textAttributes: LensSeverityTextAttributes + val lineAttributes: LensSeverityTextAttributes init { val lightThemeColor = ColorUtil.saturate(ColorUtil.darker(baseColor, lightThemeDarkening), 1) val darkThemeColor = ColorUtil.desaturate(ColorUtil.brighter(baseColor, darkThemeBrightening), 2) val textColor = JBColor(lightThemeColor, darkThemeColor) - colorAttributes = LensSeverityTextAttributes(foregroundColor = textColor, fontStyle = Font.ITALIC) + val lineColor = JBColor(toAlpha(lightThemeColor, 10), toAlpha(darkThemeColor, 13)) + + textAttributes = LensSeverityTextAttributes(foregroundColor = textColor, fontStyle = Font.ITALIC) + lineAttributes = LensSeverityTextAttributes(backgroundColor = lineColor) } companion object { diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverityTextAttributes.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverityTextAttributes.kt index c74d984..7eaf9c8 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverityTextAttributes.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensSeverityTextAttributes.kt @@ -4,11 +4,19 @@ import com.intellij.openapi.editor.markup.UnmodifiableTextAttributes import com.intellij.ui.JBColor import java.awt.Font -class LensSeverityTextAttributes(private val foregroundColor: JBColor, private val fontStyle: Int = Font.PLAIN) : UnmodifiableTextAttributes() { - override fun getForegroundColor(): JBColor { +class LensSeverityTextAttributes( + private val foregroundColor: JBColor? = null, + private val backgroundColor: JBColor? = null, + private val fontStyle: Int = Font.PLAIN, +) : UnmodifiableTextAttributes() { + override fun getForegroundColor(): JBColor? { return foregroundColor } + override fun getBackgroundColor(): JBColor? { + return backgroundColor + } + override fun getFontType(): Int { return fontStyle }