mirror of
https://github.com/chylex/IntelliJ-Inspection-Lens.git
synced 2024-11-25 16:42:54 +01:00
Compare commits
4 Commits
beab4af5ca
...
c8cacbe252
Author | SHA1 | Date | |
---|---|---|---|
c8cacbe252 | |||
13f3c86afa | |||
|
94602bd8f9 | ||
97422e1d42 |
@ -2,9 +2,9 @@
|
||||
|
||||
IntelliJ plugin that shows errors, warnings, and other inspection highlights inline.
|
||||
|
||||
Simply install the plugin and inspection descriptions will appear on the right side of the lines. Shown inspection severities are **Errors**, **Warnings**, **Weak Warnings**, **Server Problems**, **Typos**, and other inspections from plugins or future IntelliJ versions that have a high enough severity level. Each severity has a different color, with support for both light and dark themes.
|
||||
After installing the plugin, inspection descriptions will appear after the ends of lines, and the lines will be highlighted with a background color. Shown inspection severities are **Errors**, **Warnings**, **Weak Warnings**, **Server Problems**, **Grammar Errors**, **Typos**, and other inspections from plugins or future IntelliJ versions that have a high enough severity level. Each severity has a different color, with support for both light and dark themes.
|
||||
|
||||
The plugin is not customizable outside the ability to disable/enable the plugin without restarting the IDE. If the defaults don't work for you, I would recommend either trying the [Inline Error](https://plugins.jetbrains.com/plugin/17302-inlineerror) plugin which can be customized, or proposing your change in the [issue tracker](https://github.com/chylex/IntelliJ-Inspection-Lens/issues).
|
||||
Note: The plugin is not customizable outside the ability to disable/enable the plugin without restarting the IDE. If the defaults don't work for you, I recommend trying the [Inline Error](https://plugins.jetbrains.com/plugin/17302-inlineerror) plugin which can be customized, building your own version of Inspection Lens, or proposing your change in the [issue tracker](https://github.com/chylex/IntelliJ-Inspection-Lens/issues).
|
||||
|
||||
Inspired by [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) for Visual Studio Code, and [Inline Error](https://plugins.jetbrains.com/plugin/17302-inlineerror) for IntelliJ Platform.
|
||||
|
||||
|
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "com.chylex.intellij.inspectionlens"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.chylex.intellij.inspectionlens
|
||||
|
||||
import com.chylex.intellij.inspectionlens.editor.EditorInlayLensManager
|
||||
import com.chylex.intellij.inspectionlens.editor.EditorLensManager
|
||||
import com.chylex.intellij.inspectionlens.editor.LensMarkupModelListener
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
@ -36,7 +36,7 @@ internal object InspectionLens {
|
||||
*/
|
||||
fun uninstall() {
|
||||
forEachOpenEditor {
|
||||
EditorInlayLensManager.remove(it.editor)
|
||||
EditorLensManager.remove(it.editor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
package com.chylex.intellij.inspectionlens.editor
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.Inlay
|
||||
import com.intellij.openapi.editor.InlayProperties
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.util.Key
|
||||
|
||||
/**
|
||||
* Manages visible inspection lenses for an [Editor].
|
||||
*/
|
||||
class EditorInlayLensManager private constructor(private val editor: Editor) {
|
||||
companion object {
|
||||
private val EDITOR_KEY = Key<EditorInlayLensManager>(EditorInlayLensManager::class.java.name)
|
||||
|
||||
/**
|
||||
* Highest allowed severity for the purposes of sorting multiple highlights at the same offset.
|
||||
* The value is a little higher than the highest [com.intellij.lang.annotation.HighlightSeverity], in case severities with higher values are introduced in the future.
|
||||
*/
|
||||
private const val MAXIMUM_SEVERITY = 500
|
||||
private const val MAXIMUM_POSITION = ((Int.MAX_VALUE / MAXIMUM_SEVERITY) * 2) - 1
|
||||
|
||||
fun getOrCreate(editor: Editor): EditorInlayLensManager {
|
||||
return editor.getUserData(EDITOR_KEY) ?: EditorInlayLensManager(editor).also { editor.putUserData(EDITOR_KEY, it) }
|
||||
}
|
||||
|
||||
fun remove(editor: Editor) {
|
||||
val manager = editor.getUserData(EDITOR_KEY)
|
||||
if (manager != null) {
|
||||
manager.hideAll()
|
||||
editor.putUserData(EDITOR_KEY, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInlayHintOffset(info: HighlightInfo): Int {
|
||||
// Ensures a highlight at the end of a line does not overflow to the next line.
|
||||
return info.actualEndOffset - 1
|
||||
}
|
||||
|
||||
internal fun getInlayHintPriority(position: Int, severity: Int): Int {
|
||||
// Sorts highlights first by position on the line, then by severity.
|
||||
val positionBucket = position.coerceIn(0, MAXIMUM_POSITION) * MAXIMUM_SEVERITY
|
||||
// The multiplication can overflow, but subtracting overflowed result from Int.MAX_VALUE does not break continuity.
|
||||
val positionFactor = Integer.MAX_VALUE - positionBucket
|
||||
val severityFactor = severity.coerceIn(0, MAXIMUM_SEVERITY) - MAXIMUM_SEVERITY
|
||||
return positionFactor + severityFactor
|
||||
}
|
||||
}
|
||||
|
||||
private val inlays = mutableMapOf<RangeHighlighter, Inlay<LensRenderer>>()
|
||||
|
||||
private fun show(highlighterWithInfo: HighlighterWithInfo) {
|
||||
val (highlighter, info) = highlighterWithInfo
|
||||
val currentInlay = inlays[highlighter]
|
||||
if (currentInlay != null && currentInlay.isValid) {
|
||||
currentInlay.renderer.setPropertiesFrom(info)
|
||||
currentInlay.update()
|
||||
}
|
||||
else {
|
||||
val offset = getInlayHintOffset(info)
|
||||
val priority = getInlayHintPriority(info)
|
||||
val renderer = LensRenderer(info)
|
||||
val properties = InlayProperties().relatesToPrecedingText(true).disableSoftWrapping(true).priority(priority)
|
||||
|
||||
editor.inlayModel.addAfterLineEndElement(offset, properties, renderer)?.let {
|
||||
inlays[highlighter] = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showAll(highlightersWithInfo: Collection<HighlighterWithInfo>) {
|
||||
executeInInlayBatchMode(highlightersWithInfo.size) { highlightersWithInfo.forEach(::show) }
|
||||
}
|
||||
|
||||
private fun hide(highlighter: RangeHighlighter) {
|
||||
inlays.remove(highlighter)?.dispose()
|
||||
}
|
||||
|
||||
fun hideAll(highlighters: Collection<RangeHighlighter>) {
|
||||
executeInInlayBatchMode(highlighters.size) { highlighters.forEach(::hide) }
|
||||
}
|
||||
|
||||
fun hideAll() {
|
||||
if (inlays.isNotEmpty()) {
|
||||
executeInInlayBatchMode(inlays.size) { inlays.values.forEach(Inlay<*>::dispose) }
|
||||
inlays.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInlayHintPriority(info: HighlightInfo): Int {
|
||||
val startOffset = info.actualStartOffset
|
||||
val positionOnLine = startOffset - getLineStartOffset(startOffset)
|
||||
return getInlayHintPriority(positionOnLine, info.severity.myVal)
|
||||
}
|
||||
|
||||
private fun getLineStartOffset(offset: Int): Int {
|
||||
val position = editor.offsetToLogicalPosition(offset)
|
||||
return editor.document.getLineStartOffset(position.line)
|
||||
}
|
||||
|
||||
private fun executeInInlayBatchMode(operations: Int, block: () -> Unit) {
|
||||
editor.inlayModel.execute(operations > 1000, block)
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
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, private var lineBackground: EditorLensLineBackground) {
|
||||
fun update(info: HighlightInfo): Boolean {
|
||||
val editor = inlay.editor
|
||||
|
||||
if (!inlay.tryUpdate(info)) {
|
||||
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? {
|
||||
val inlay = EditorLensInlay.show(editor, info) ?: return null
|
||||
val lineBackground = EditorLensLineBackground.show(editor, info)
|
||||
return EditorLens(inlay, lineBackground)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.chylex.intellij.inspectionlens.editor
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.Inlay
|
||||
import com.intellij.openapi.editor.InlayProperties
|
||||
|
||||
@JvmInline
|
||||
internal value class EditorLensInlay(private val inlay: Inlay<LensRenderer>) {
|
||||
val editor
|
||||
get() = inlay.editor
|
||||
|
||||
fun tryUpdate(info: HighlightInfo): Boolean {
|
||||
if (!inlay.isValid) {
|
||||
return false
|
||||
}
|
||||
|
||||
inlay.renderer.setPropertiesFrom(info)
|
||||
inlay.update()
|
||||
return true
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
inlay.dispose()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun show(editor: Editor, info: HighlightInfo): EditorLensInlay? {
|
||||
val offset = getInlayHintOffset(info)
|
||||
val priority = getInlayHintPriority(editor, info)
|
||||
|
||||
val renderer = LensRenderer(info)
|
||||
val properties = InlayProperties().relatesToPrecedingText(true).disableSoftWrapping(true).priority(priority)
|
||||
|
||||
return editor.inlayModel.addAfterLineEndElement(offset, properties, renderer)?.let(::EditorLensInlay)
|
||||
}
|
||||
|
||||
/**
|
||||
* Highest allowed severity for the purposes of sorting multiple highlights at the same offset.
|
||||
* The value is a little higher than the highest [com.intellij.lang.annotation.HighlightSeverity], in case severities with higher values are introduced in the future.
|
||||
*/
|
||||
private const val MAXIMUM_SEVERITY = 500
|
||||
private const val MAXIMUM_POSITION = ((Int.MAX_VALUE / MAXIMUM_SEVERITY) * 2) - 1
|
||||
|
||||
private fun getInlayHintOffset(info: HighlightInfo): Int {
|
||||
// Ensures a highlight at the end of a line does not overflow to the next line.
|
||||
return info.actualEndOffset - 1
|
||||
}
|
||||
|
||||
fun getInlayHintPriority(position: Int, severity: Int): Int {
|
||||
// Sorts highlights first by position on the line, then by severity.
|
||||
val positionBucket = position.coerceIn(0, MAXIMUM_POSITION) * MAXIMUM_SEVERITY
|
||||
// The multiplication can overflow, but subtracting overflowed result from Int.MAX_VALUE does not break continuity.
|
||||
val positionFactor = Integer.MAX_VALUE - positionBucket
|
||||
val severityFactor = severity.coerceIn(0, MAXIMUM_SEVERITY) - MAXIMUM_SEVERITY
|
||||
return positionFactor + severityFactor
|
||||
}
|
||||
|
||||
private fun getInlayHintPriority(editor: Editor, info: HighlightInfo): Int {
|
||||
val startOffset = info.actualStartOffset
|
||||
val positionOnLine = startOffset - getLineStartOffset(editor, startOffset)
|
||||
return getInlayHintPriority(positionOnLine, info.severity.myVal)
|
||||
}
|
||||
|
||||
private fun getLineStartOffset(editor: Editor, offset: Int): Int {
|
||||
val position = editor.offsetToLogicalPosition(offset)
|
||||
return editor.document.getLineStartOffset(position.line)
|
||||
}
|
||||
}
|
||||
}
|
@ -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 - 1).coerceAtLeast(startOffset)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.chylex.intellij.inspectionlens.editor
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.util.Key
|
||||
import java.util.IdentityHashMap
|
||||
|
||||
/**
|
||||
* Manages visible inspection lenses for an [Editor].
|
||||
*/
|
||||
class EditorLensManager private constructor(private val editor: Editor) {
|
||||
companion object {
|
||||
private val EDITOR_KEY = Key<EditorLensManager>(EditorLensManager::class.java.name)
|
||||
|
||||
fun getOrCreate(editor: Editor): EditorLensManager {
|
||||
return editor.getUserData(EDITOR_KEY) ?: EditorLensManager(editor).also { editor.putUserData(EDITOR_KEY, it) }
|
||||
}
|
||||
|
||||
fun remove(editor: Editor) {
|
||||
val manager = editor.getUserData(EDITOR_KEY)
|
||||
if (manager != null) {
|
||||
manager.hideAll()
|
||||
editor.putUserData(EDITOR_KEY, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val lenses = IdentityHashMap<RangeHighlighter, EditorLens>()
|
||||
|
||||
private fun show(highlighterWithInfo: HighlighterWithInfo) {
|
||||
val (highlighter, info) = highlighterWithInfo
|
||||
|
||||
val existingLens = lenses[highlighter]
|
||||
if (existingLens != null) {
|
||||
if (existingLens.update(info)) {
|
||||
return
|
||||
}
|
||||
|
||||
existingLens.hide()
|
||||
}
|
||||
|
||||
val newLens = EditorLens.show(editor, info)
|
||||
if (newLens != null) {
|
||||
lenses[highlighter] = newLens
|
||||
}
|
||||
else if (existingLens != null) {
|
||||
lenses.remove(highlighter)
|
||||
}
|
||||
}
|
||||
|
||||
fun show(highlightersWithInfo: Collection<HighlighterWithInfo>) {
|
||||
executeInBatchMode(highlightersWithInfo.size) {
|
||||
highlightersWithInfo.forEach(::show)
|
||||
}
|
||||
}
|
||||
|
||||
private fun hide(highlighter: RangeHighlighter) {
|
||||
lenses.remove(highlighter)?.hide()
|
||||
}
|
||||
|
||||
fun hide(highlighters: Collection<RangeHighlighter>) {
|
||||
executeInBatchMode(highlighters.size) {
|
||||
highlighters.forEach(::hide)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideAll() {
|
||||
executeInBatchMode(lenses.size) {
|
||||
lenses.values.forEach(EditorLens::hide)
|
||||
lenses.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
editor.inlayModel.execute(true) { action() }
|
||||
}
|
||||
else {
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
@ -14,13 +14,13 @@ import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.Key
|
||||
|
||||
/**
|
||||
* Listens for inspection highlights and reports them to [EditorInlayLensManager].
|
||||
* Listens for inspection highlights and reports them to [EditorLensManager].
|
||||
*/
|
||||
internal class LensMarkupModelListener private constructor(editor: Editor) : MarkupModelListener {
|
||||
private val lens = EditorInlayLensManager.getOrCreate(editor)
|
||||
private val lensManager = EditorLensManager.getOrCreate(editor)
|
||||
|
||||
private val showOnDispatchThread = DebouncingInvokeOnDispatchThread(lens::showAll)
|
||||
private val hideOnDispatchThread = DebouncingInvokeOnDispatchThread(lens::hideAll)
|
||||
private val showOnDispatchThread = DebouncingInvokeOnDispatchThread(lensManager::show)
|
||||
private val hideOnDispatchThread = DebouncingInvokeOnDispatchThread(lensManager::hide)
|
||||
|
||||
override fun afterAdded(highlighter: RangeHighlighterEx) {
|
||||
showIfValid(highlighter)
|
||||
@ -81,7 +81,7 @@ internal class LensMarkupModelListener private constructor(editor: Editor) : Mar
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a new [LensMarkupModelListener] to the [Editor], and reports all existing inspection highlights to [EditorInlayLensManager].
|
||||
* Attaches a new [LensMarkupModelListener] to the [Editor], and reports all existing inspection highlights to [EditorLensManager].
|
||||
*/
|
||||
fun register(editor: Editor, disposable: Disposable) {
|
||||
if (editor.getUserData(EDITOR_KEY) != null) {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -6,17 +6,21 @@
|
||||
<description><![CDATA[
|
||||
Shows errors, warnings, and other inspection highlights inline.
|
||||
<br><br>
|
||||
Simply install the plugin and inspection descriptions will appear on the right side of the lines.
|
||||
Shown inspection severities are <b>Errors</b>, <b>Warnings</b>, <b>Weak Warnings</b>, <b>Server Problems</b>, <b>Typos</b>, and other inspections from plugins or future IntelliJ versions that have a high enough severity level.
|
||||
After installing the plugin, inspection descriptions will appear after the ends of lines, and the lines will be highlighted with a background color.
|
||||
Shown inspection severities are <b>Errors</b>, <b>Warnings</b>, <b>Weak Warnings</b>, <b>Server Problems</b>, <b>Grammar Errors</b>, <b>Typos</b>, and other inspections from plugins or future IntelliJ versions that have a high enough severity level.
|
||||
Each severity has a different color, with support for both light and dark themes.
|
||||
<br><br>
|
||||
The plugin is not customizable outside the ability to disable/enable the plugin without restarting the IDE.
|
||||
If the defaults don't work for you, I would recommend either trying the <a href="https://plugins.jetbrains.com/plugin/17302-inlineerror">Inline Error</a> plugin which can be customized, or proposing your change in the <a href="https://github.com/chylex/IntelliJ-Inspection-Lens/issues">issue tracker</a>.
|
||||
Note: The plugin is not customizable outside the ability to disable/enable the plugin without restarting the IDE.
|
||||
If the defaults don't work for you, I recommend trying the <a href="https://plugins.jetbrains.com/plugin/17302-inlineerror">Inline Error</a> plugin which can be customized, building your own version of Inspection Lens, or proposing your change in the <a href="https://github.com/chylex/IntelliJ-Inspection-Lens/issues">issue tracker</a>.
|
||||
<br><br>
|
||||
Inspired by <a href="https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens">Error Lens</a> for VS Code, and <a href="https://plugins.jetbrains.com/plugin/17302-inlineerror">Inline Error</a> for IntelliJ Platform.
|
||||
]]></description>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
<b>Version 1.3.0</b>
|
||||
<ul>
|
||||
<li>Added background colors to lines containing inspections. (<a href="https://github.com/chylex/IntelliJ-Inspection-Lens/pull/15">PR #15</a> by <a href="https://github.com/synopss">synopss</a>)</li>
|
||||
</ul>
|
||||
<b>Version 1.2.0</b>
|
||||
<ul>
|
||||
<li>Support for IntelliJ 2023.2 EAP.</li>
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.chylex.intellij.inspectionlens
|
||||
|
||||
import com.chylex.intellij.inspectionlens.editor.EditorInlayLensManager
|
||||
import com.chylex.intellij.inspectionlens.editor.EditorLensInlay
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Nested
|
||||
@ -8,47 +8,47 @@ import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
|
||||
class EditorInlayLensManagerTest {
|
||||
class EditorLensTest {
|
||||
@Nested
|
||||
inner class Priority {
|
||||
@ParameterizedTest(name = "positionAndSeverity = {0}")
|
||||
@ValueSource(ints = [0, -1, Int.MIN_VALUE])
|
||||
fun minimumOffset(positionAndSeverity: Int) {
|
||||
assertEquals(Int.MAX_VALUE, EditorInlayLensManager.getInlayHintPriority(positionAndSeverity, Int.MAX_VALUE))
|
||||
assertEquals(Int.MAX_VALUE, EditorLensInlay.getInlayHintPriority(positionAndSeverity, Int.MAX_VALUE))
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "position = {0}")
|
||||
@ValueSource(ints = [8_589_933, Int.MAX_VALUE])
|
||||
fun maximumOffset(position: Int) {
|
||||
assertEquals(Int.MIN_VALUE + 295, EditorInlayLensManager.getInlayHintPriority(position, Int.MIN_VALUE))
|
||||
assertEquals(Int.MIN_VALUE + 295, EditorLensInlay.getInlayHintPriority(position, Int.MIN_VALUE))
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "severity = {0}")
|
||||
@ValueSource(ints = [0, 1, 250, 499, 500])
|
||||
fun firstPriorityBucket(severity: Int) {
|
||||
assertEquals(Int.MAX_VALUE - 500 + severity, EditorInlayLensManager.getInlayHintPriority(0, severity))
|
||||
assertEquals(Int.MAX_VALUE - 500 + severity, EditorLensInlay.getInlayHintPriority(0, severity))
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "severity = {0}")
|
||||
@ValueSource(ints = [0, 1, 250, 499, 500])
|
||||
fun secondPriorityBucket(severity: Int) {
|
||||
assertEquals(Int.MAX_VALUE - 1000 + severity, EditorInlayLensManager.getInlayHintPriority(1, severity))
|
||||
assertEquals(Int.MAX_VALUE - 1000 + severity, EditorLensInlay.getInlayHintPriority(1, severity))
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "severity = {0}")
|
||||
@ValueSource(ints = [0, 1, 250, 499, 500])
|
||||
fun middlePriorityBucket(severity: Int) {
|
||||
assertEquals(-353 + severity, EditorInlayLensManager.getInlayHintPriority(4294967, severity))
|
||||
assertEquals(-353 + severity, EditorLensInlay.getInlayHintPriority(4294967, severity))
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "severity = {0}")
|
||||
@ValueSource(ints = [0, 1, 250, 499, 500])
|
||||
fun penultimatePriorityBucket(severity: Int) {
|
||||
assertEquals(Int.MIN_VALUE + 295 + 500 + severity, EditorInlayLensManager.getInlayHintPriority(8_589_932, severity))
|
||||
assertEquals(Int.MIN_VALUE + 295 + 500 + severity, EditorLensInlay.getInlayHintPriority(8_589_932, severity))
|
||||
}
|
||||
|
||||
/**
|
||||
* If any of these change, re-evaluate [EditorInlayLensManager.MAXIMUM_SEVERITY] and the priority calculations.
|
||||
* If any of these change, re-evaluate [EditorLensInlay.MAXIMUM_SEVERITY] and the priority calculations.
|
||||
*/
|
||||
@Nested
|
||||
inner class IdeaHighlightSeverityAssumptions {
|
Loading…
Reference in New Issue
Block a user