1
0
mirror of https://github.com/chylex/IntelliJ-Inspection-Lens.git synced 2025-04-22 18:15:45 +02:00

Hide line background highlighters in folded regions to fix documentation rendering

Closes 
This commit is contained in:
chylex 2024-12-24 19:24:48 +01:00
parent 632a052ff9
commit 8ee14ff55e
Signed by: chylex
SSH Key Fingerprint: SHA256:WqM8X/1DDn11LbYM0H5wsqZUjbcKxVsic37L+ERcF4o
5 changed files with 51 additions and 28 deletions

View File

@ -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) }

View File

@ -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)

View File

@ -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()
}
}

View File

@ -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)
}
}
}

View File

@ -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
}
}
}