Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## [Unreleased]

## [0.5.7]
### Changed
- Added feature to enable and disable all problems with a keybind (thanks to khopland)
- Added feature to hover and click in a problem to get the fix context window (thanks to khopland)

## [0.5.6]
### Changed
- Added 2 settings options to disable HTML stripping and XML unescaping
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
<h3 align="center">InlineProblems</h3>

<!-- Plugin description -->
Plugin to show problems like errors and warnings inside the text editor (inline) for IDEs based on the IntelliJ Platform, inspired by Error Lens and InlineError
Plugin to show problems like errors and warnings inside the text editor (inline) for IDEs based on the IntelliJ Platform, inspired by Error Lens and InlineError.

You can turn this plugin on and off with the keyboard shortcut `alt+u`, additional shortcuts can be configured in the settings.
<!-- Plugin description end -->

<p align="center">
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pluginGroup = org.OverEngineer
pluginName = InlineProblems
pluginRepositoryUrl = https://github.com/OverEngineer/InlineProblems
# SemVer format -> https://semver.org
pluginVersion = 0.5.6
pluginVersion = 0.5.7

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 212.5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,24 @@

if (projectManager != null) {
List<InlineProblem> problems = new ArrayList<>();
if (settingsState.isEnableInlineProblem())
for (var project : projectManager.getOpenProjects()) {
if (!project.isInitialized() || project.isDisposed())
continue;

for (var project : projectManager.getOpenProjects()) {
if (!project.isInitialized() || project.isDisposed())
continue;
FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
for (var editor : fileEditorManager.getAllEditors()) {

FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
for (var editor : fileEditorManager.getAllEditors()) {
if (editor.getFile() == null || FileNameUtil.ignoreFile(editor.getFile().getName())) {
continue;
}

if (editor.getFile() == null || FileNameUtil.ignoreFile(editor.getFile().getName())) {
continue;
}

if (editor instanceof TextEditor) {
var textEditor = (TextEditor) editor;
problems.addAll(getProblemsInEditor(textEditor));
if (editor instanceof TextEditor) {
var textEditor = (TextEditor) editor;
problems.addAll(getProblemsInEditor(textEditor));
}
}
}
}

problemManager.updateFromNewActiveProblems(problems);
}
Expand All @@ -119,7 +119,7 @@
mergingUpdateQueue.queue(new Update("scan") {
@Override
public void run() {
List<InlineProblem> problems = getProblemsInEditor(textEditor);
List<InlineProblem> problems = settingsState.isEnableInlineProblem() ? List.of() : getProblemsInEditor(textEditor);

problemManager.updateFromNewActiveProblemsForProjectAndFile(
problems,
Expand Down Expand Up @@ -158,8 +158,7 @@
!highlightInfo.getDescription().isEmpty() &&
problemTextBeginningFilterList.stream()
.noneMatch(f -> highlightInfo.getDescription().stripLeading().toLowerCase().startsWith(f.toLowerCase())) &&
fileEndOffset >= highlightInfo.getStartOffset()
;
fileEndOffset >= highlightInfo.getStartOffset();
}

return false;
Expand All @@ -169,7 +168,7 @@

InlineProblem newProblem = new InlineProblem(
document.getLineNumber(highlightInfo.getStartOffset()),
textEditor.getFile().getPath(),

Check warning on line 171 in src/main/java/org/overengineer/inlineproblems/DocumentMarkupModelScanner.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Nullability and data flow problems

Method invocation `getPath` may produce `NullPointerException`

Check warning on line 171 in src/main/java/org/overengineer/inlineproblems/DocumentMarkupModelScanner.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Nullability and data flow problems

Method invocation `getPath` may produce `NullPointerException`
highlightInfo,
textEditor,
h,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void drawProblemLabel(InlineProblem problem) {
problem,
drawDetails.getTextColor(),
drawDetails.getBackgroundColor(),
drawDetails.getTextColor().brighter(),
settings
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
package org.overengineer.inlineproblems;

import com.intellij.codeInsight.hints.presentation.InputHandler;
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
import com.intellij.ide.ui.AntialiasingType;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorCustomElementRenderer;
import com.intellij.openapi.editor.Inlay;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.impl.FontInfo;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.paint.EffectPainter;
import lombok.Getter;
import lombok.Setter;
import org.jdesktop.swingx.action.ActionManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.overengineer.inlineproblems.entities.InlineProblem;
import org.overengineer.inlineproblems.settings.SettingsState;
import org.overengineer.inlineproblems.utils.FontUtil;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.font.FontRenderContext;


@Getter
public class InlineProblemLabel implements EditorCustomElementRenderer {

public class InlineProblemLabel implements EditorCustomElementRenderer, InputHandler {
private final String text;
private final Color textColor;
private final Color backgroundColor;
private final Color hoverColor;
private final boolean isDrawBox;
private final boolean isRoundedCorners;
private final boolean isFillBackground;
private boolean hovered;
private final boolean clickableContext;
private Inlay<?> inlay;
private final int actualStartOffset;

@Setter
private boolean isBlockElement;
Expand All @@ -47,10 +63,12 @@ public InlineProblemLabel(
final InlineProblem problem,
final Color textColor,
final Color backgroundColor,
final Color hoverColor,
final SettingsState settings
) {
this.textColor = textColor;
this.backgroundColor = backgroundColor;
this.hoverColor = hoverColor;
this.isDrawBox = settings.isDrawBoxesAroundErrorLabels();
this.isRoundedCorners = settings.isRoundedCornerBoxes();
this.text = problem.getText();
Expand All @@ -59,6 +77,9 @@ public InlineProblemLabel(

this.isUseEditorFont = settings.isUseEditorFont();
this.inlayFontSizeDelta = settings.getInlayFontSizeDelta();
this.hovered = false;
this.actualStartOffset = problem.getActualStartffset();
this.clickableContext = settings.isClickableContext();
}

@Override
Expand All @@ -80,7 +101,7 @@ public int calcWidthInPixels(@NotNull Editor editor) {
@Override
public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rectangle targetRegion, @NotNull TextAttributes textAttributes) {
Editor editor = inlay.getEditor();

this.inlay = inlay;
// These offsets are applied here and not in the calc functions itself because we use it to shrink the drawn stuff a little bit
int width = calcWidthInPixels(inlay) + DRAW_BOX_WIDTH_OFFSET;
int height = calcHeightInPixels(inlay) + DRAW_BOX_HEIGHT_OFFSET;
Expand All @@ -92,7 +113,7 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
// Apply delta on the boxes
if (inlayFontSizeDelta != 0 && editorFontSize > inlayFontSizeDelta) {
height -= inlayFontSizeDelta;
targetRegionY += (int)(inlayFontSizeDelta / 1.5);
targetRegionY += (int) (inlayFontSizeDelta / 1.5);
}

if (isDrawBox) {
Expand All @@ -118,14 +139,13 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
5
);
}
}
else {
graphics.drawRect(
targetRegion.x,
targetRegionY,
width,
height
);
} else {
graphics.drawRect(
targetRegion.x,
targetRegionY,
width,
height
);

if (isFillBackground) {
graphics.fillRect(
Expand All @@ -138,7 +158,7 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
}
}

graphics.setColor(textColor);
graphics.setColor(hovered ? hoverColor : textColor);

graphics.setFont(FontUtil.getActiveFont(editor));

Expand All @@ -147,10 +167,63 @@ public void paint(@NotNull Inlay inlay, @NotNull Graphics graphics, @NotNull Rec
targetRegion.x + DRAW_STRING_LINE_PLACEMENT_OFFSET_X,
targetRegion.y + DRAW_STRING_LINE_PLACEMENT_OFFSET_Y + editor.getAscent()
);
if (hovered)
EffectPainter.LINE_UNDERSCORE.paint(
(Graphics2D) graphics,
targetRegion.x - DRAW_BOX_WIDTH_OFFSET,
targetRegion.y + editor.getAscent() ,
width + (DRAW_BOX_WIDTH_OFFSET * 2),
editor.getAscent(),
FontUtil.getActiveFont(editor));
}

private void setHovered(boolean hovered) {
if (!this.clickableContext || this.hovered == hovered) {
return;
}
this.hovered = hovered;
if (inlay != null)
inlay.repaint();
}

@Override
public @Nullable GutterIconRenderer calcGutterIconRenderer(@NotNull Inlay inlay) {
return EditorCustomElementRenderer.super.calcGutterIconRenderer(inlay);
}

@Override
public void mouseClicked(@NotNull MouseEvent mouseEvent, @NotNull Point point) {
if (!clickableContext) {
return;
}
if (mouseEvent.getButton() == MouseEvent.BUTTON1) {
mouseEvent.consume();

var editor = inlay.getEditor();
editor.getCaretModel().moveToOffset(actualStartOffset);
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);

var action = ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS);
if (action == null) {
Project project = editor.getProject();
if (project == null) return;
PsiFile psiFileInEditor = PsiUtilBase.getPsiFileInEditor(editor, project);
if (psiFileInEditor == null) return;
new ShowIntentionActionsHandler().invoke(project, editor, psiFileInEditor, false);
} else {
ActionUtil.invokeAction((AnAction) action, editor.getComponent(), "EditorInlay", null, null);
}
}
}

@Override
public void mouseMoved(@NotNull MouseEvent mouseEvent, @NotNull Point point) {
setHovered(true);
}

@Override
public void mouseExited() {
setHovered(false);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.overengineer.inlineproblems.actions;

import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import org.jetbrains.annotations.NotNull;
import org.overengineer.inlineproblems.DocumentMarkupModelScanner;
import org.overengineer.inlineproblems.Notifier;
import org.overengineer.inlineproblems.bundles.SettingsBundle;
import org.overengineer.inlineproblems.settings.SettingsState;

public class EnableInlineProblemsAction extends AnAction {

@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
SettingsState settingsState = SettingsState.getInstance();
if (settingsState.isEnableInlineProblemsNotifications()) {
Notifier.notify(SettingsBundle.message(
settingsState.isEnableInlineProblem()
? "settings.enableInlineProblem.disabled"
: "settings.enableInlineProblem.enabled"),
NotificationType.INFORMATION,
anActionEvent.getProject()
);
}
settingsState.setEnableInlineProblem(!settingsState.isEnableInlineProblem());
ApplicationManager.getApplication().invokeAndWait(DocumentMarkupModelScanner.getInstance()::scanForProblemsManually);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.overengineer.inlineproblems.actions;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
import org.overengineer.inlineproblems.settings.SettingsState;

public class ShowErrorsAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
SettingsState settingsState = SettingsState.getInstance();
settingsState.setShowErrors(!settingsState.isShowErrors());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.overengineer.inlineproblems.actions;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
import org.overengineer.inlineproblems.settings.SettingsState;

public class ShowInfosAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
SettingsState settingsState = SettingsState.getInstance();
settingsState.setShowInfos(!settingsState.isShowInfos());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.overengineer.inlineproblems.actions;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
import org.overengineer.inlineproblems.settings.SettingsState;

public class ShowWarningsAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
SettingsState settingsState = SettingsState.getInstance();
settingsState.setShowWarnings(!settingsState.isShowWarnings());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.overengineer.inlineproblems.actions;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
import org.overengineer.inlineproblems.settings.SettingsState;

public class ShowWeakWarningsAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
SettingsState settingsState = SettingsState.getInstance();
settingsState.setShowWeakWarnings(!settingsState.isShowWeakWarnings());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class InlineProblem {
private DrawDetails drawDetails;

private int actualEndOffset;
private int actualStartffset;

private boolean isBlockElement = false;

Expand Down Expand Up @@ -68,6 +69,7 @@ public InlineProblem(
this.project = textEditor.getEditor().getProject();
this.highlightInfoStartOffset = highlightInfo.hashCode();
this.rangeHighlighterHashCode = rangeHighlighter.hashCode();
this.actualStartffset = highlightInfo.getStartOffset();

if (highlightInfo.getActualEndOffset() == 0)
this.actualEndOffset = highlightInfo.getActualEndOffset();
Expand Down
Loading
Loading