mirror of
https://github.com/chylex/IntelliJ-Inspection-Lens.git
synced 2024-11-26 01:42:52 +01:00
Compare commits
No commits in common. "0aff0f49ae221741412bfb1b0907183892a2ffc6" and "7c3910854d0bb1d73f4d43a8260d304a38a5dcec" have entirely different histories.
0aff0f49ae
...
7c3910854d
@ -14,10 +14,6 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
intellij {
|
intellij {
|
||||||
version.set("2022.2")
|
version.set("2022.2")
|
||||||
updateSinceUntilBuild.set(false)
|
updateSinceUntilBuild.set(false)
|
||||||
@ -31,10 +27,6 @@ tasks.buildSearchableOptions {
|
|||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
kotlinOptions.jvmTarget = "11"
|
kotlinOptions.jvmTarget = "11"
|
||||||
kotlinOptions.freeCompilerArgs = listOf(
|
kotlinOptions.freeCompilerArgs = listOf(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.chylex.intellij.inspectionlens
|
package com.chylex.intellij.inspectionlens
|
||||||
|
|
||||||
import com.chylex.intellij.inspectionlens.EditorInlayLensManager.Companion.MAXIMUM_SEVERITY
|
|
||||||
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.Inlay
|
import com.intellij.openapi.editor.Inlay
|
||||||
@ -15,13 +14,6 @@ class EditorInlayLensManager private constructor(private val editor: Editor) {
|
|||||||
companion object {
|
companion object {
|
||||||
private val KEY = Key<EditorInlayLensManager>(EditorInlayLensManager::class.java.name)
|
private val KEY = Key<EditorInlayLensManager>(EditorInlayLensManager::class.java.name)
|
||||||
|
|
||||||
/**
|
|
||||||
* Highest allowed severity for the purposes of sorting multiple highlights at the same offset.
|
|
||||||
* A [MAXIMUM_SEVERITY] of 500 allows for 8 589 933 positions in the document before sorting breaks down.
|
|
||||||
* 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
|
|
||||||
|
|
||||||
fun getOrCreate(editor: Editor): EditorInlayLensManager {
|
fun getOrCreate(editor: Editor): EditorInlayLensManager {
|
||||||
return editor.getUserData(KEY) ?: EditorInlayLensManager(editor).also { editor.putUserData(KEY, it) }
|
return editor.getUserData(KEY) ?: EditorInlayLensManager(editor).also { editor.putUserData(KEY, it) }
|
||||||
}
|
}
|
||||||
@ -38,19 +30,6 @@ class EditorInlayLensManager private constructor(private val editor: Editor) {
|
|||||||
// Ensures a highlight at the end of a line does not overflow to the next line.
|
// Ensures a highlight at the end of a line does not overflow to the next line.
|
||||||
return info.actualEndOffset - 1
|
return info.actualEndOffset - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getInlayHintPriority(offset: Int, severity: Int): Int {
|
|
||||||
// Sorts highlights first by offset in the document, then by severity.
|
|
||||||
val positionBucket = offset.coerceAtLeast(0) * MAXIMUM_SEVERITY.toLong()
|
|
||||||
val positionFactor = (Int.MAX_VALUE - MAXIMUM_SEVERITY - positionBucket).coerceAtLeast(Int.MIN_VALUE + 1L).toInt()
|
|
||||||
val severityFactor = severity.coerceIn(0, MAXIMUM_SEVERITY)
|
|
||||||
// The result is between (Int.MIN_VALUE + 1)..Int.MAX_VALUE, allowing for negation without overflow.
|
|
||||||
return positionFactor + severityFactor
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getInlayHintPriority(info: HighlightInfo): Int {
|
|
||||||
return getInlayHintPriority(info.actualEndOffset, info.severity.myVal)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val inlays = mutableMapOf<RangeHighlighter, Inlay<LensRenderer>>()
|
private val inlays = mutableMapOf<RangeHighlighter, Inlay<LensRenderer>>()
|
||||||
@ -64,9 +43,8 @@ class EditorInlayLensManager private constructor(private val editor: Editor) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val offset = getInlayHintOffset(info)
|
val offset = getInlayHintOffset(info)
|
||||||
val priority = getInlayHintPriority(info)
|
|
||||||
val renderer = LensRenderer(info)
|
val renderer = LensRenderer(info)
|
||||||
val properties = InlayProperties().relatesToPrecedingText(true).disableSoftWrapping(true).priority(priority)
|
val properties = InlayProperties().relatesToPrecedingText(true).disableSoftWrapping(true).priority(-offset)
|
||||||
|
|
||||||
editor.inlayModel.addAfterLineEndElement(offset, properties, renderer)?.let {
|
editor.inlayModel.addAfterLineEndElement(offset, properties, renderer)?.let {
|
||||||
inlays[highlighter] = it
|
inlays[highlighter] = it
|
||||||
|
@ -42,23 +42,13 @@ class LensRenderer(info: HighlightInfo) : HintRenderer(null) {
|
|||||||
private val ATTRIBUTES_SINGLETON = TextAttributes(null, null, null, null, Font.ITALIC)
|
private val ATTRIBUTES_SINGLETON = TextAttributes(null, null, null, null, Font.ITALIC)
|
||||||
|
|
||||||
private fun getValidDescriptionText(text: String?): String {
|
private fun getValidDescriptionText(text: String?): String {
|
||||||
return if (text.isNullOrBlank()) " " else addMissingPeriod(convertHtmlToText(text))
|
return if (text.isNullOrBlank()) " " else addMissingPeriod(StringUtil.unescapeXmlEntities(StringUtil.stripHtml(text, " ")))
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertHtmlToText(potentialHtml: String): String {
|
|
||||||
return potentialHtml
|
|
||||||
.ifContains('<') { StringUtil.stripHtml(it, " ") }
|
|
||||||
.ifContains('&', StringUtil::unescapeXmlEntities)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addMissingPeriod(text: String): String {
|
private fun addMissingPeriod(text: String): String {
|
||||||
return if (text.endsWith('.')) text else "$text."
|
return if (text.endsWith('.')) text else "$text."
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun String.ifContains(charToTest: Char, action: (String) -> String): String {
|
|
||||||
return if (this.contains(charToTest)) action(this) else this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fixBaselineForTextRendering(rect: Rectangle) {
|
private fun fixBaselineForTextRendering(rect: Rectangle) {
|
||||||
rect.y += 1
|
rect.y += 1
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
package com.chylex.intellij.inspectionlens
|
|
||||||
|
|
||||||
import com.intellij.lang.annotation.HighlightSeverity
|
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
|
||||||
import org.junit.jupiter.api.Nested
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest
|
|
||||||
import org.junit.jupiter.params.provider.ValueSource
|
|
||||||
|
|
||||||
class EditorInlayLensManagerTest {
|
|
||||||
@Nested
|
|
||||||
inner class Priority {
|
|
||||||
@ParameterizedTest(name = "offsetAndSeverity = {0}")
|
|
||||||
@ValueSource(ints = [0, -1, Int.MIN_VALUE])
|
|
||||||
fun minimumOffset(offsetAndSeverity: Int) {
|
|
||||||
assertEquals(Int.MAX_VALUE, EditorInlayLensManager.getInlayHintPriority(offsetAndSeverity, Int.MAX_VALUE))
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest(name = "offset = {0}")
|
|
||||||
@ValueSource(ints = [8_589_934, Int.MAX_VALUE])
|
|
||||||
fun maximumOffset(offset: Int) {
|
|
||||||
assertEquals(Int.MIN_VALUE + 1, EditorInlayLensManager.getInlayHintPriority(offset, 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))
|
|
||||||
}
|
|
||||||
|
|
||||||
@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))
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest(name = "severity = {0}")
|
|
||||||
@ValueSource(ints = [0, 1, 250, 499, 500])
|
|
||||||
fun penultimatePriorityBucket(severity: Int) {
|
|
||||||
assertEquals(Int.MIN_VALUE + 295 + severity, EditorInlayLensManager.getInlayHintPriority(8_589_933, severity))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If any of these change, re-evaluate [EditorInlayLensManager.MAXIMUM_SEVERITY] and the priority calculations.
|
|
||||||
*/
|
|
||||||
@Nested
|
|
||||||
inner class IdeaAssumptions {
|
|
||||||
@Test
|
|
||||||
fun smallestSeverityHasNotChanged() {
|
|
||||||
assertEquals(10, HighlightSeverity.DEFAULT_SEVERITIES.minOf(HighlightSeverity::myVal))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun highestSeverityHasNotChanged() {
|
|
||||||
assertEquals(400, HighlightSeverity.DEFAULT_SEVERITIES.maxOf(HighlightSeverity::myVal))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user