Skip to content

Commit

Permalink
add inlay tag number for fix fields
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Timofte committed Sep 14, 2024
1 parent 9afed05 commit 21dd8df
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 95 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

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

4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ repositories {

// Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog
dependencies {
implementation("org.slf4j:slf4j-api:1.7.32")
implementation("org.slf4j:slf4j-simple:1.7.32")
implementation("org.projectlombok:lombok:1.18.24")
annotationProcessor("org.projectlombok:lombok:1.18.24")
testImplementation(libs.junit)

// IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package ac.quant.quickfixspec.inlay;

import com.intellij.codeInsight.hints.*;
import com.intellij.codeInsight.hints.presentation.*;
import com.intellij.lang.Language;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorFontType;

Check warning on line 8 in src/main/java/ac/quant/quickfixspec/inlay/QuickfixInlayHintsProvider.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import

Unused import `import com.intellij.openapi.editor.colors.EditorFontType;`
import com.intellij.psi.*;
import com.intellij.psi.xml.*;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.intellij.codeInsight.hints.presentation.InlayPresentation;

Check warning on line 14 in src/main/java/ac/quant/quickfixspec/inlay/QuickfixInlayHintsProvider.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import

Unused import `import com.intellij.codeInsight.hints.presentation.InlayPresentation;`
import com.intellij.codeInsight.hints.presentation.PresentationFactory;

Check warning on line 15 in src/main/java/ac/quant/quickfixspec/inlay/QuickfixInlayHintsProvider.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import

Unused import `import com.intellij.codeInsight.hints.presentation.PresentationFactory;`

import javax.swing.*;
import java.awt.*;

Check warning on line 18 in src/main/java/ac/quant/quickfixspec/inlay/QuickfixInlayHintsProvider.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import

Unused import `import java.awt.*;`

@SuppressWarnings("UnstableApiUsage")
@Slf4j
public class QuickfixInlayHintsProvider implements InlayHintsProvider<NoSettings> {

private static final SettingsKey<NoSettings> KEY = new SettingsKey<>("fix.tag.inlay.hints");

@Override
public @NotNull SettingsKey<NoSettings> getKey() {
return KEY;
}

@Override
public @NotNull String getName() {
return "Quickfix tag inlay hints";
}

@Override
public @NotNull NoSettings createSettings() {
return new NoSettings();
}

@Override
public @NotNull InlayHintsCollector getCollectorFor(
@NotNull PsiFile file,
@NotNull Editor editor,
@NotNull NoSettings settings,
@NotNull InlayHintsSink sink) {
log.info("getCollectorFor");
return new MyCollector();
}

private static class MyCollector implements InlayHintsCollector {

@Override
public boolean collect(@NotNull PsiElement element, @NotNull Editor editor, @NotNull InlayHintsSink sink){

if (!(element instanceof XmlAttributeValue attributeValue)) {
return true;
}

PsiElement parent = attributeValue.getParent();

if (!(parent instanceof XmlAttribute attribute)) {
return true;
}

// We're interested in attributes named "name" and "group"
if (!"name".equals(attribute.getName()) && !"group".equals(attribute.getName())) {
return true;
}

XmlTag tag = attribute.getParent();

// We're interested in "field" and "group" tags
if (!"field".equals(tag.getName()) && !"group".equals(tag.getName())) {
return true;
}

// Get the field name
String fieldName = attributeValue.getValue();

// Find the tag number
String tagNumber = findTagNumber(getRootTag(tag), fieldName);

if (tagNumber != null) {
// Set the top and bottom insets using magic numbers for better alignment

Check notice on line 85 in src/main/java/ac/quant/quickfixspec/inlay/QuickfixInlayHintsProvider.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Method can be extracted

It's possible to extract method returning 'centeredPresentation' from a long surrounding method
// TODO - Use a better way to calculate insets
int topInset = 6;
int bottomInset = 2;

// Create the inlay presentation
PresentationFactory factory = new PresentationFactory(editor);
InlayPresentation textPresentation = factory.text(" (" + tagNumber + ")");

// Wrap with InsetPresentation
InlayPresentation centeredPresentation = new InsetPresentation(
textPresentation,
0, // Left inset
0, // Right inset
topInset, // Top inset
bottomInset // Bottom inset
);

int offset = attributeValue.getTextRange().getEndOffset();
sink.addInlineElement(offset, false, centeredPresentation, false);
}

return true;
}

private @Nullable String findTagNumber(PsiElement root, String fieldName) {
if (!(root instanceof XmlTag rootTag)) {
return null;
}

// Assuming the "fields" tag is a direct child of the root
XmlTag[] fieldsTags = rootTag.findSubTags("fields");

for (XmlTag fieldsTag : fieldsTags) {
for (XmlTag fieldTag : fieldsTag.findSubTags("field")) {
String nameAttr = fieldTag.getAttributeValue("name");
if (fieldName.equals(nameAttr)) {
return fieldTag.getAttributeValue("number");
}
}
}
return null;
}

// Helper method to navigate to the root tag
private @Nullable XmlTag getRootTag(PsiElement element) {
PsiElement current = element;
while (current != null && !(current instanceof PsiFile)) {
if (current instanceof XmlTag && "fix".equals(((XmlTag) current).getName())) {
return (XmlTag) current;
}
current = current.getParent();
}
return null;
}
}

@Override
public boolean isLanguageSupported(@NotNull Language language) {
return language.isKindOf(XMLLanguage.INSTANCE);
}

public @NotNull SettingsKey<NoSettings> getSettingsKey() {
return KEY;
}

@Override
public @NotNull String getPreviewText() {
return "";
}

@Override
public @NotNull ImmediateConfigurable createConfigurable(@NotNull NoSettings settings) {
return new ImmediateConfigurable() {
@Override
public @NotNull JComponent createComponent(@NotNull ChangeListener changeListener) {
return new JPanel();
}
};
}
}

20 changes: 0 additions & 20 deletions src/main/kotlin/com/github/dantimofte/quickfixspec/MyBundle.kt

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

9 changes: 8 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
<id>com.github.dantimofte.quickfixspec</id>
<name>quickfix-spec</name>
<name>Quickfix-Spec</name>
<vendor>dantimofte</vendor>

<depends>com.intellij.modules.platform</depends>
Expand All @@ -12,6 +12,13 @@
<toolWindow factoryClass="com.github.dantimofte.quickfixspec.toolWindow.MyToolWindowFactory" id="MyToolWindow"/>
</extensions>

<!-- Register the Inlay Hints Provider -->
<extensions defaultExtensionNs="com.intellij.codeInsight">
<inlayProvider
implementationClass="ac.quant.quickfixspec.inlay.QuickfixInlayHintsProvider"
language="XML"/>
</extensions>

<applicationListeners>
<listener class="com.github.dantimofte.quickfixspec.listeners.MyApplicationActivationListener" topic="com.intellij.openapi.application.ApplicationActivationListener"/>
</applicationListeners>
Expand Down

0 comments on commit 21dd8df

Please sign in to comment.