diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensFeatures.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensFeatures.kt index 09b2c65..c7365b5 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensFeatures.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensFeatures.kt @@ -2,6 +2,7 @@ package com.chylex.intellij.inspectionlens.editor import com.intellij.openapi.Disposable import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.ex.FoldingModelEx import com.intellij.openapi.editor.ex.MarkupModelEx import com.intellij.openapi.editor.impl.DocumentMarkupModel import com.intellij.openapi.util.Disposer @@ -13,6 +14,7 @@ import com.intellij.openapi.util.Key internal class EditorLensFeatures private constructor( editor: Editor, private val markupModel: MarkupModelEx, + foldingModel: FoldingModelEx?, disposable: Disposable ) { private val lensManager = EditorLensManager(editor) @@ -22,6 +24,8 @@ internal class EditorLensFeatures private constructor( init { markupModel.addMarkupModelListener(disposable, markupModelListener) markupModelListener.showAllValid(markupModel.allHighlighters) + + foldingModel?.addListener(LensFoldingModelListener(lensManager), disposable) } private fun refresh() { @@ -38,7 +42,8 @@ internal class EditorLensFeatures private constructor( } val markupModel = DocumentMarkupModel.forDocument(editor.document, editor.project, false) as? MarkupModelEx ?: return - val features = EditorLensFeatures(editor, markupModel, disposable) + val foldingModel = editor.foldingModel as? FoldingModelEx + val features = EditorLensFeatures(editor, markupModel, foldingModel, disposable) editor.putUserData(EDITOR_KEY, features) Disposer.register(disposable) { editor.putUserData(EDITOR_KEY, null) } 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 df7e645..6f9bab6 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensManager.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/EditorLensManager.kt @@ -56,6 +56,10 @@ internal class EditorLensManager(private val editor: Editor) { } } + fun onFoldRegionsChanged() { + lenses.values.forEach(EditorLens::onFoldRegionsChanged) + } + sealed interface Command { fun apply(lensManager: EditorLensManager) diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensFoldingModelListener.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensFoldingModelListener.kt new file mode 100644 index 0000000..e49e49d --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/LensFoldingModelListener.kt @@ -0,0 +1,12 @@ +package com.chylex.intellij.inspectionlens.editor + +import com.intellij.openapi.editor.ex.FoldingListener + +/** + * Listens for code folding events and reports them to [EditorLensManager]. + */ +internal class LensFoldingModelListener(private val lensManager: EditorLensManager) : FoldingListener { + override fun onFoldProcessingEnd() { + lensManager.onFoldRegionsChanged() + } +} diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLens.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLens.kt index da1adf4..2b7b7f1 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLens.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLens.kt @@ -4,15 +4,18 @@ import com.chylex.intellij.inspectionlens.settings.LensSettingsState import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.openapi.editor.Editor -internal class EditorLens private constructor(private var inlay: EditorLensInlay, private var lineBackground: EditorLensLineBackground) { +internal class EditorLens private constructor(private var inlay: EditorLensInlay, private var lineBackground: EditorLensLineBackground, private var severity: LensSeverity) { fun update(info: HighlightInfo, settings: LensSettingsState): Boolean { val editor = inlay.editor + val oldSeverity = severity + + severity = LensSeverity.from(info.severity) if (!inlay.tryUpdate(info)) { inlay = EditorLensInlay.show(editor, info, settings) ?: return false } - if (lineBackground.shouldRecreate(info)) { + if (lineBackground.isInvalid || oldSeverity != severity) { lineBackground.hide(editor) lineBackground = EditorLensLineBackground.show(editor, info) } @@ -20,18 +23,21 @@ internal class EditorLens private constructor(private var inlay: EditorLensInlay return true } + fun onFoldRegionsChanged() { + lineBackground.onFoldRegionsChanged(inlay.editor, severity) + } + fun hide() { - val editor = inlay.editor - inlay.hide() - lineBackground.hide(editor) + lineBackground.hide(inlay.editor) } companion object { fun show(editor: Editor, info: HighlightInfo, settings: LensSettingsState): EditorLens? { val inlay = EditorLensInlay.show(editor, info, settings) ?: return null val lineBackground = EditorLensLineBackground.show(editor, info) - return EditorLens(inlay, lineBackground) + val severity = LensSeverity.from(info.severity) + return EditorLens(inlay, lineBackground, severity) } } } diff --git a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLensLineBackground.kt b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLensLineBackground.kt index 4f10a2a..40f5a12 100644 --- a/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLensLineBackground.kt +++ b/src/main/kotlin/com/chylex/intellij/inspectionlens/editor/lens/EditorLensLineBackground.kt @@ -2,33 +2,21 @@ package com.chylex.intellij.inspectionlens.editor.lens import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.ex.RangeHighlighterEx import com.intellij.openapi.editor.markup.HighlighterLayer import com.intellij.openapi.editor.markup.HighlighterTargetArea.LINES_IN_RANGE import com.intellij.openapi.editor.markup.RangeHighlighter +import com.intellij.openapi.editor.markup.TextAttributes @JvmInline internal value class EditorLensLineBackground(private val highlighter: RangeHighlighter) { - @Suppress("RedundantIf") - fun shouldRecreate(info: HighlightInfo): Boolean { - if (!highlighter.isValid) { - return true + val isInvalid + get() = !highlighter.isValid + + fun onFoldRegionsChanged(editor: Editor, severity: LensSeverity) { + if (highlighter is RangeHighlighterEx) { + highlighter.textAttributes = getAttributes(editor, highlighter.startOffset, highlighter.endOffset, severity) } - - 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) { @@ -42,12 +30,20 @@ internal value class EditorLensLineBackground(private val highlighter: RangeHigh val severity = LensSeverity.from(info.severity) val layer = getHighlightLayer(severity) + val attributes = getAttributes(editor, startOffset, endOffset, severity) - return EditorLensLineBackground(editor.markupModel.addRangeHighlighter(startOffset, endOffset, layer, severity.lineAttributes, LINES_IN_RANGE)) + return EditorLensLineBackground(editor.markupModel.addRangeHighlighter(startOffset, endOffset, layer, attributes, LINES_IN_RANGE)) } private fun getHighlightLayer(severity: LensSeverity): Int { return HighlighterLayer.CARET_ROW - 100 - severity.ordinal } + + private fun getAttributes(editor: Editor, startOffset: Int, endOffset: Int, severity: LensSeverity): TextAttributes? { + return if (editor.foldingModel.let { it.isOffsetCollapsed(startOffset) || it.isOffsetCollapsed(endOffset) }) + null + else + severity.lineAttributes + } } }