1
0
mirror of https://github.com/chylex/IntelliJ-Inspection-Lens.git synced 2025-09-17 14:24:48 +02:00

8 Commits

15 changed files with 139 additions and 59 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1,3 +1 @@
github: chylex
patreon: chylex
ko_fi: chylex

1
.gitignore vendored
View File

@@ -3,4 +3,5 @@
!/.idea/runConfigurations
/.gradle/
/.intellijPlatform/
/build/

View File

@@ -2,9 +2,9 @@
Displays errors, warnings, and other inspections inline. Highlights the background of lines with inspections. Supports light and dark themes out of the box.
By default, the plugin shows **Errors**, **Warnings**, **Weak Warnings**, **Server Problems**, **Grammar Errors**, **Typos**, and other inspections with a high enough severity level. Configure visible severities in **Settings | Tools | Inspection Lens**.
By default, the plugin shows **Errors**, **Warnings**, **Weak Warnings**, **Server Problems**, **Grammar Errors**, **Typos**, and other inspections with a high enough severity level. Left-click an inspection to show quick fixes. Middle-click an inspection to navigate to the relevant code in the editor.
Left-click an inspection to show quick fixes. Middle-click an inspection to navigate to the relevant code in the editor.
Configure appearance, behavior of clicking on inspections, and visible severities in **Settings | Tools | Inspection Lens**.
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.

View File

@@ -1,48 +1,57 @@
@file:Suppress("ConvertLambdaToReference")
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.8.0"
id("org.jetbrains.intellij") version "1.17.0"
kotlin("jvm")
id("org.jetbrains.intellij.platform")
}
group = "com.chylex.intellij.inspectionlens"
version = "1.5"
version = "1.5.1"
repositories {
mavenCentral()
intellijPlatform {
defaultRepositories()
}
}
intellij {
version.set("2023.3.3")
updateSinceUntilBuild.set(false)
dependencies {
intellijPlatform {
intellijIdeaUltimate("2023.3.3")
bundledPlugin("tanvd.grazi")
plugins.add("tanvd.grazi")
// https://plugins.jetbrains.com/plugin/12175-grazie-lite/versions
// plugin("tanvd.grazi", "233.13135.14")
}
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
}
intellijPlatform {
pluginConfiguration {
ideaVersion {
sinceBuild.set("233.11361.10")
untilBuild.set(provider { null })
}
}
}
kotlin {
jvmToolchain(17)
compilerOptions {
freeCompilerArgs = listOf(
"-X" + "jvm-default=all"
)
}
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
}
tasks.patchPluginXml {
sinceBuild.set("233.11361.10")
}
tasks.buildSearchableOptions {
enabled = false
}
tasks.test {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions.freeCompilerArgs = listOf(
"-Xjvm-default=all"
)
val testSnapshot by intellijPlatformTesting.testIde.registering {
version = "LATEST-EAP-SNAPSHOT"
useInstaller = false
}

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

6
gradlew vendored
View File

@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

22
gradlew.bat vendored
View File

@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View File

@@ -1 +1,8 @@
rootProject.name = "InspectionLens"
pluginManagement {
plugins {
kotlin("jvm") version "1.9.21"
id("org.jetbrains.intellij.platform") version "2.2.1"
}
}

View File

@@ -2,8 +2,13 @@ package com.chylex.intellij.inspectionlens.editor.lens
import com.intellij.codeInsight.daemon.impl.IntentionsUI
import com.intellij.codeInsight.hint.HintManager
import com.intellij.codeInsight.intention.actions.ShowIntentionActionsAction
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
import com.intellij.lang.LangBundle
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager
@@ -18,6 +23,19 @@ internal object IntentionsPopup {
}
private fun tryShow(editor: Editor): Boolean {
// If the IDE uses the default Show Intentions action and handler,
// use the handler directly to bypass additional logic from the action.
val action = ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS)
if (action.javaClass === ShowIntentionActionsAction::class.java) {
return tryShowWithDefaultHandler(editor)
}
else {
ActionUtil.invokeAction(action, editor.component, ActionPlaces.EDITOR_INLAY, null, null)
return true
}
}
private fun tryShowWithDefaultHandler(editor: Editor): Boolean {
val project = editor.project ?: return false
val file = PsiUtilBase.getPsiFileInEditor(editor, project) ?: return false

View File

@@ -1,5 +1,6 @@
package com.chylex.intellij.inspectionlens.editor.lens
import com.chylex.intellij.inspectionlens.settings.LensHoverMode
import com.chylex.intellij.inspectionlens.settings.LensSettingsState
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.HintRenderer
@@ -16,6 +17,7 @@ import com.intellij.ui.paint.EffectPainter
import java.awt.Cursor
import java.awt.Graphics
import java.awt.Graphics2D
import java.awt.MouseInfo
import java.awt.Point
import java.awt.Rectangle
import java.awt.event.MouseEvent
@@ -25,8 +27,7 @@ import javax.swing.SwingUtilities
/**
* Renders the text of an inspection lens.
*/
class LensRenderer(private var info: HighlightInfo, settings: LensSettingsState) : HintRenderer(null), InputHandler {
private val useEditorFont = settings.useEditorFont
class LensRenderer(private var info: HighlightInfo, private val settings: LensSettingsState) : HintRenderer(null), InputHandler {
private lateinit var inlay: Inlay<*>
private lateinit var attributes: LensSeverityTextAttributes
private var extraRightPadding = 0
@@ -54,7 +55,7 @@ class LensRenderer(private var info: HighlightInfo, settings: LensSettingsState)
fixBaselineForTextRendering(r)
super.paint(inlay, g, r, textAttributes)
if (hovered) {
if (hovered && isHoveringText()) {
paintHoverEffect(inlay, g, r)
}
}
@@ -67,7 +68,7 @@ class LensRenderer(private var info: HighlightInfo, settings: LensSettingsState)
val font = editor.colorsScheme.getFont(EditorFontType.PLAIN)
val x = r.x + TEXT_HORIZONTAL_PADDING
val y = r.y + editor.ascent + 1
val y = r.y + editor.ascent
val w = inlay.widthInPixels - UNDERLINE_WIDTH_REDUCTION - extraRightPadding
val h = editor.descent
@@ -80,7 +81,7 @@ class LensRenderer(private var info: HighlightInfo, settings: LensSettingsState)
}
override fun useEditorFont(): Boolean {
return useEditorFont
return settings.useEditorFont
}
override fun mouseMoved(event: MouseEvent, translated: Point) {
@@ -92,6 +93,10 @@ class LensRenderer(private var info: HighlightInfo, settings: LensSettingsState)
}
private fun setHovered(hovered: Boolean) {
if (hovered && settings.lensHoverMode == LensHoverMode.DISABLED) {
return
}
if (this.hovered == hovered) {
return
}
@@ -108,22 +113,33 @@ class LensRenderer(private var info: HighlightInfo, settings: LensSettingsState)
}
override fun mousePressed(event: MouseEvent, translated: Point) {
if (!isHoveringText(translated)) {
val hoverMode = settings.lensHoverMode
if (hoverMode == LensHoverMode.DISABLED || !isHoveringText(translated)) {
return
}
if (SwingUtilities.isLeftMouseButton(event) || SwingUtilities.isMiddleMouseButton(event)) {
if (event.button.let { it == MouseEvent.BUTTON1 || it == MouseEvent.BUTTON2 }) {
event.consume()
val editor = inlay.editor
moveToOffset(editor, info.actualStartOffset)
if (SwingUtilities.isLeftMouseButton(event)) {
if ((event.button == MouseEvent.BUTTON1) xor (hoverMode != LensHoverMode.DEFAULT)) {
IntentionsPopup.show(editor)
}
}
}
private fun isHoveringText(): Boolean {
val bounds = inlay.bounds ?: return false
val translatedPoint = MouseInfo.getPointerInfo().location.apply {
SwingUtilities.convertPointFromScreen(this, inlay.editor.contentComponent)
translate(-bounds.x, -bounds.y)
}
return isHoveringText(translatedPoint)
}
private fun isHoveringText(point: Point): Boolean {
return point.x >= HOVER_HORIZONTAL_PADDING
&& point.y >= 4

View File

@@ -13,11 +13,13 @@ import com.intellij.openapi.ui.DialogPanel
import com.intellij.openapi.util.Disposer
import com.intellij.ui.DisabledTraversalPolicy
import com.intellij.ui.EditorTextFieldCellRenderer.SimpleRendererComponent
import com.intellij.ui.SimpleListCellRenderer
import com.intellij.ui.components.JBCheckBox
import com.intellij.ui.dsl.builder.Cell
import com.intellij.ui.dsl.builder.RightGap
import com.intellij.ui.dsl.builder.Row
import com.intellij.ui.dsl.builder.RowLayout
import com.intellij.ui.dsl.builder.bindItem
import com.intellij.ui.dsl.builder.bindSelected
import com.intellij.ui.dsl.builder.panel
import java.awt.Cursor
@@ -74,6 +76,20 @@ class LensApplicationConfigurable : BoundConfigurable("Inspection Lens"), Config
val settings = settingsService.state
return panel {
group("Appearance") {
row {
checkBox("Use editor font").bindSelected(settings::useEditorFont)
}
}
group("Behavior") {
row("Hover mode:") {
val items = LensHoverMode.values().toList()
val renderer = SimpleListCellRenderer.create("", LensHoverMode::description)
comboBox(items, renderer).bindItem(settings::lensHoverMode) { settings.lensHoverMode = it ?: LensHoverMode.DEFAULT }
}
}
group("Shown Severities") {
for ((id, severity, textAttributes) in allSeverities) {
row {
@@ -89,12 +105,6 @@ class LensApplicationConfigurable : BoundConfigurable("Inspection Lens"), Config
checkBox("Other").bindSelected(settings::showUnknownSeverities)
}
}
group("Appearance") {
row {
checkBox("Use editor font").bindSelected(settings::useEditorFont)
}
}
}
}

View File

@@ -0,0 +1,7 @@
package com.chylex.intellij.inspectionlens.settings
enum class LensHoverMode(val description: String) {
DISABLED("Disabled"),
DEFAULT("Left click shows intentions, middle click jumps to highlight"),
SWAPPED("Left click jumps to highlight, middle click shows intentions")
}

View File

@@ -21,6 +21,7 @@ class LensSettingsState : SimplePersistentStateComponent<LensSettingsState.State
var showUnknownSeverities by property(true)
var useEditorFont by property(true)
var lensHoverMode by enum(LensHoverMode.DEFAULT)
}
@get:Synchronized
@@ -31,6 +32,9 @@ class LensSettingsState : SimplePersistentStateComponent<LensSettingsState.State
val useEditorFont
get() = state.useEditorFont
val lensHoverMode
get() = state.lensHoverMode
override fun loadState(state: State) {
super.loadState(state)
update()

View File

@@ -6,14 +6,20 @@
<description><![CDATA[
Displays errors, warnings, and other inspections inline. Highlights the background of lines with inspections. Supports light and dark themes out of the box.
<br><br>
By default, the plugin shows <b>Errors</b>, <b>Warnings</b>, <b>Weak Warnings</b>, <b>Server Problems</b>, <b>Grammar Errors</b>, <b>Typos</b>, and other inspections with a high enough severity level. Configure visible severities in <b>Settings | Tools | Inspection Lens</a>.
By default, the plugin shows <b>Errors</b>, <b>Warnings</b>, <b>Weak Warnings</b>, <b>Server Problems</b>, <b>Grammar Errors</b>, <b>Typos</b>, and other inspections with a high enough severity level. Left-click an inspection to show quick fixes. Middle-click an inspection to navigate to the relevant code in the editor.
<br><br>
Left-click an inspection to show quick fixes. Middle-click an inspection to navigate to the relevant code in the editor.
Configure appearance, behavior of clicking on inspections, and visible severities in <b>Settings | Tools | Inspection Lens</b>.
<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.5.1</b>
<ul>
<li>Added option to change the behavior of clicking on inspections.</li>
<li>Fixed broken quick fixes in Rider and CLion Nova.</li>
<li>Fixed hover underline not rendering correctly with some combinations of high DPI and line height settings.</li>
</ul>
<b>Version 1.5</b>
<ul>
<li>Added possibility to left-click an inspection to show quick fixes.</li>