1
0
mirror of https://github.com/chylex/IntelliJ-Inspection-Lens.git synced 2025-05-02 20:34:06 +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.Disposable
import com.intellij.openapi.editor.Editor 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.ex.MarkupModelEx
import com.intellij.openapi.editor.impl.DocumentMarkupModel import com.intellij.openapi.editor.impl.DocumentMarkupModel
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
@ -13,6 +14,7 @@ import com.intellij.openapi.util.Key
internal class EditorLensFeatures private constructor( internal class EditorLensFeatures private constructor(
editor: Editor, editor: Editor,
private val markupModel: MarkupModelEx, private val markupModel: MarkupModelEx,
foldingModel: FoldingModelEx?,
disposable: Disposable disposable: Disposable
) { ) {
private val lensManager = EditorLensManager(editor) private val lensManager = EditorLensManager(editor)
@ -22,6 +24,8 @@ internal class EditorLensFeatures private constructor(
init { init {
markupModel.addMarkupModelListener(disposable, markupModelListener) markupModel.addMarkupModelListener(disposable, markupModelListener)
markupModelListener.showAllValid(markupModel.allHighlighters) markupModelListener.showAllValid(markupModel.allHighlighters)
foldingModel?.addListener(LensFoldingModelListener(lensManager), disposable)
} }
private fun refresh() { 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 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) editor.putUserData(EDITOR_KEY, features)
Disposer.register(disposable) { editor.putUserData(EDITOR_KEY, null) } 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 { sealed interface Command {
fun apply(lensManager: EditorLensManager) 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.codeInsight.daemon.impl.HighlightInfo
import com.intellij.openapi.editor.Editor 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 { fun update(info: HighlightInfo, settings: LensSettingsState): Boolean {
val editor = inlay.editor val editor = inlay.editor
val oldSeverity = severity
severity = LensSeverity.from(info.severity)
if (!inlay.tryUpdate(info)) { if (!inlay.tryUpdate(info)) {
inlay = EditorLensInlay.show(editor, info, settings) ?: return false inlay = EditorLensInlay.show(editor, info, settings) ?: return false
} }
if (lineBackground.shouldRecreate(info)) { if (lineBackground.isInvalid || oldSeverity != severity) {
lineBackground.hide(editor) lineBackground.hide(editor)
lineBackground = EditorLensLineBackground.show(editor, info) lineBackground = EditorLensLineBackground.show(editor, info)
} }
@ -20,18 +23,21 @@ internal class EditorLens private constructor(private var inlay: EditorLensInlay
return true return true
} }
fun onFoldRegionsChanged() {
lineBackground.onFoldRegionsChanged(inlay.editor, severity)
}
fun hide() { fun hide() {
val editor = inlay.editor
inlay.hide() inlay.hide()
lineBackground.hide(editor) lineBackground.hide(inlay.editor)
} }
companion object { companion object {
fun show(editor: Editor, info: HighlightInfo, settings: LensSettingsState): EditorLens? { fun show(editor: Editor, info: HighlightInfo, settings: LensSettingsState): EditorLens? {
val inlay = EditorLensInlay.show(editor, info, settings) ?: return null val inlay = EditorLensInlay.show(editor, info, settings) ?: return null
val lineBackground = EditorLensLineBackground.show(editor, info) 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.codeInsight.daemon.impl.HighlightInfo
import com.intellij.openapi.editor.Editor 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.HighlighterLayer
import com.intellij.openapi.editor.markup.HighlighterTargetArea.LINES_IN_RANGE import com.intellij.openapi.editor.markup.HighlighterTargetArea.LINES_IN_RANGE
import com.intellij.openapi.editor.markup.RangeHighlighter import com.intellij.openapi.editor.markup.RangeHighlighter
import com.intellij.openapi.editor.markup.TextAttributes
@JvmInline @JvmInline
internal value class EditorLensLineBackground(private val highlighter: RangeHighlighter) { internal value class EditorLensLineBackground(private val highlighter: RangeHighlighter) {
@Suppress("RedundantIf") val isInvalid
fun shouldRecreate(info: HighlightInfo): Boolean { get() = !highlighter.isValid
if (!highlighter.isValid) {
return true 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) { fun hide(editor: Editor) {
@ -42,12 +30,20 @@ internal value class EditorLensLineBackground(private val highlighter: RangeHigh
val severity = LensSeverity.from(info.severity) val severity = LensSeverity.from(info.severity)
val layer = getHighlightLayer(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 { private fun getHighlightLayer(severity: LensSeverity): Int {
return HighlighterLayer.CARET_ROW - 100 - severity.ordinal 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
}
} }
} }