1.0.0
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
**/.idea/*
|
||||
!**/.idea/runConfigurations
|
||||
!**/.idea/scopes
|
||||
|
||||
.gradle
|
||||
build
|
||||
|
||||
.qodana
|
||||
21
.idea/runConfigurations/buildPlugin.xml
generated
Normal file
21
.idea/runConfigurations/buildPlugin.xml
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="buildPlugin" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="buildPlugin -x test" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list />
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
21
.idea/runConfigurations/runIde.xml
generated
Normal file
21
.idea/runConfigurations/runIde.xml
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="runIde" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value=":runIde" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list />
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
10
README.md
10
README.md
@@ -0,0 +1,10 @@
|
||||
# Show Comment Plugin
|
||||
IDEA 智能注释插件
|
||||
|
||||
English Note:
|
||||
- Show javadoc comments for calling methods at the end of the line.
|
||||
- Show javadoc comments in the Project view Tree structure.
|
||||
|
||||
Chinese Note:
|
||||
- 在行末显示调用方法的文档注释。
|
||||
- 在结构树显示文档注释。
|
||||
50
build.gradle
Normal file
50
build.gradle
Normal file
@@ -0,0 +1,50 @@
|
||||
plugins {
|
||||
id 'org.jetbrains.intellij' version '1.3.1'
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group 'io.github.linwancen'
|
||||
version '1.0.0.' + (new Date().format('yyyy.MM.dd_HH.mm'))
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
|
||||
}
|
||||
|
||||
// See https://github.com/JetBrains/gradle-intellij-plugin/
|
||||
intellij {
|
||||
version = ideaVersion
|
||||
plugins = ['java']
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
tasks.withType(Javadoc) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
patchPluginXml {
|
||||
// The performance of 2019.3 has been greatly improved.
|
||||
// change plugins without restarting the IDE in 2020.1.
|
||||
sinceBuild = '201.1'
|
||||
untilBuild = ''
|
||||
changeNotes = """
|
||||
Code optimization | 代码优化
|
||||
"""
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
publishPlugin {
|
||||
token = System.getenv("PUBLISH_TOKEN")
|
||||
}
|
||||
1
gradle.properties
Normal file
1
gradle.properties
Normal file
@@ -0,0 +1 @@
|
||||
ideaVersion=2020.1
|
||||
2
settings.gradle
Normal file
2
settings.gradle
Normal file
@@ -0,0 +1,2 @@
|
||||
rootProject.name = 'show-comment'
|
||||
|
||||
187
src/main/java/io/github/linwancen/plugin/comment/LineEnd.java
Normal file
187
src/main/java/io/github/linwancen/plugin/comment/LineEnd.java
Normal file
@@ -0,0 +1,187 @@
|
||||
package io.github.linwancen.plugin.comment;
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorLinePainter;
|
||||
import com.intellij.openapi.editor.LineExtensionInfo;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBColor;
|
||||
import io.github.linwancen.plugin.comment.settings.AppSettingsState;
|
||||
import io.github.linwancen.plugin.comment.utils.CommentFactory;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiDocCommentUtils;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiMethodCommentFactory;
|
||||
import io.github.linwancen.plugin.comment.utils.SkipUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class LineEnd extends EditorLinePainter {
|
||||
@Override
|
||||
public @Nullable Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project,
|
||||
@NotNull VirtualFile file, int lineNumber) {
|
||||
if (!AppSettingsState.getInstance().showLineEndComment) {
|
||||
return null;
|
||||
}
|
||||
if (DumbService.isDumb(project)) {
|
||||
return null;
|
||||
}
|
||||
FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file);
|
||||
PsiElement psiElement = psiElementFrom(viewProvider, lineNumber);
|
||||
PsiDocComment docComment = psiDocCommentFrom(psiElement);
|
||||
String comment = PsiDocCommentUtils.getCommentText(docComment);
|
||||
if (comment == null) {
|
||||
return null;
|
||||
}
|
||||
LineExtensionInfo info = new LineExtensionInfo(" //" + comment, getNormalAttributes());
|
||||
return Collections.singletonList(info);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiDocComment psiDocCommentFrom(PsiElement psiElement) {
|
||||
if (psiElement == null) {
|
||||
return null;
|
||||
}
|
||||
if (psiElement instanceof PsiClass) {
|
||||
PsiClass psiClass = (PsiClass) psiElement;
|
||||
if (SkipUtils.skip(psiClass)) {
|
||||
return null;
|
||||
}
|
||||
return CommentFactory.fromSrcOrByteCode(psiClass);
|
||||
}
|
||||
if (psiElement instanceof PsiMethod) {
|
||||
PsiMethod psiMethod = (PsiMethod) psiElement;
|
||||
if (SkipUtils.skip(psiMethod.getContainingClass())) {
|
||||
return null;
|
||||
}
|
||||
return PsiMethodCommentFactory.from(psiMethod);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static final String[] KEYS = {
|
||||
"if",
|
||||
"for",
|
||||
"new",
|
||||
"=",
|
||||
"return",
|
||||
};
|
||||
|
||||
private static @Nullable PsiElement psiElementFrom(FileViewProvider viewProvider, int lineNumber) {
|
||||
if (viewProvider == null || !viewProvider.hasLanguage(JavaLanguage.INSTANCE)) {
|
||||
return null;
|
||||
}
|
||||
Document document = viewProvider.getDocument();
|
||||
if (document == null) {
|
||||
return null;
|
||||
}
|
||||
if (document.getLineCount() < lineNumber) {
|
||||
return null;
|
||||
}
|
||||
int startOffset = document.getLineStartOffset(lineNumber);
|
||||
int endOffset = document.getLineEndOffset(lineNumber);
|
||||
String text = document.getText(new TextRange(startOffset, endOffset));
|
||||
int offset = 0;
|
||||
for (String s : KEYS) {
|
||||
int i = text.indexOf(s);
|
||||
if (i > 0) {
|
||||
offset += (i + s.length());
|
||||
break;
|
||||
}
|
||||
}
|
||||
text = text.substring(offset);
|
||||
boolean startWithSymbol = false;
|
||||
char[] chars = text.toCharArray();
|
||||
// skip symbol and space
|
||||
for (char c : chars) {
|
||||
if (Character.isLetter(c)) {
|
||||
break;
|
||||
}
|
||||
if (!Character.isSpaceChar(c)) {
|
||||
startWithSymbol = true;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
offset += startOffset;
|
||||
if (startWithSymbol) {
|
||||
startOffset = 0;
|
||||
}
|
||||
PsiElement element = viewProvider.findElementAt(offset, JavaLanguage.INSTANCE);
|
||||
if (!(element instanceof PsiIdentifier)) {
|
||||
return null;
|
||||
}
|
||||
return parentElementOf(element, startOffset, endOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement parentElementOf(PsiElement element, int startOffset, int endOffset) {
|
||||
// method call
|
||||
PsiMethodCallExpression call =
|
||||
PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class, false, startOffset);
|
||||
if (call != null) {
|
||||
// skip double comment when method call in new line:
|
||||
// someObject // someMethodComment
|
||||
// .someMethod(); // someMethodComment
|
||||
if ((call.getNode().getStartOffset() + call.getNode().getTextLength()) > endOffset) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return call.resolveMethod();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// new
|
||||
PsiNewExpression newExp = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false, startOffset);
|
||||
if (newExp != null) {
|
||||
PsiMethod psiMethod = newExp.resolveMethod();
|
||||
if (psiMethod != null) {
|
||||
return psiMethod;
|
||||
}
|
||||
PsiJavaCodeReferenceElement classReference = newExp.getClassReference();
|
||||
if (classReference != null) {
|
||||
return classReference.resolve();
|
||||
}
|
||||
}
|
||||
// ::
|
||||
PsiMethodReferenceExpression ref =
|
||||
PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class, false, startOffset);
|
||||
if (ref != null) {
|
||||
return ref.resolve();
|
||||
}
|
||||
// SomeClass // SomeClassComment
|
||||
PsiJavaCodeReferenceElementImpl code =
|
||||
PsiTreeUtil.getParentOfType(element, PsiJavaCodeReferenceElementImpl.class, false, startOffset);
|
||||
if (code != null) {
|
||||
return code.resolve();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static TextAttributes getNormalAttributes() {
|
||||
EditorColorsManager colorsManager = EditorColorsManager.getInstance();
|
||||
TextAttributes attributes = colorsManager.getGlobalScheme()
|
||||
.getAttributes(DefaultLanguageHighlighterColors.LINE_COMMENT);
|
||||
if (attributes == null || attributes.getForegroundColor() == null) {
|
||||
JBColor jbColor = new JBColor(() -> Gray._183);
|
||||
return new TextAttributes(jbColor, null, null, null, Font.ITALIC);
|
||||
} else {
|
||||
// Sometimes it becomes the same color as the end of the line char, so use italic to distinguish
|
||||
attributes.setFontType(Font.ITALIC);
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
105
src/main/java/io/github/linwancen/plugin/comment/Tree.java
Normal file
105
src/main/java/io/github/linwancen/plugin/comment/Tree.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package io.github.linwancen.plugin.comment;
|
||||
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.ide.projectView.ProjectViewNode;
|
||||
import com.intellij.ide.projectView.ProjectViewNodeDecorator;
|
||||
import com.intellij.ide.projectView.impl.nodes.*;
|
||||
import com.intellij.ide.util.treeView.PresentableNodeDescriptor.ColoredFragment;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.packageDependencies.ui.PackageDependenciesNode;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import io.github.linwancen.plugin.comment.settings.AppSettingsState;
|
||||
import io.github.linwancen.plugin.comment.utils.CommentFactory;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiDocCommentUtils;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiMethodCommentFactory;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiPackageCommentFactory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Tree implements ProjectViewNodeDecorator {
|
||||
|
||||
@Override
|
||||
public void decorate(ProjectViewNode node, PresentationData data) {
|
||||
if (!AppSettingsState.getInstance().showTreeComment) {
|
||||
return;
|
||||
}
|
||||
Project project = node.getProject();
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
if (DumbService.isDumb(project)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiDocComment docComment = psiDocCommentOf(node, project);
|
||||
if (docComment == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String commentText = PsiDocCommentUtils.getCommentText(docComment);
|
||||
if (commentText == null) {
|
||||
return;
|
||||
}
|
||||
List<ColoredFragment> coloredText = data.getColoredText();
|
||||
if (coloredText.isEmpty()) {
|
||||
data.addText(data.getPresentableText(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
}
|
||||
data.addText(commentText, SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiDocComment psiDocCommentOf(ProjectViewNode<?> node, Project project) {
|
||||
if (node instanceof PsiFileNode) {
|
||||
PsiFile psiFile = ((PsiFileNode) node).getValue();
|
||||
return CommentFactory.from(psiFile);
|
||||
}
|
||||
if (node instanceof PsiDirectoryNode) {
|
||||
PsiDirectory psiDirectory = ((PsiDirectoryNode) node).getValue();
|
||||
return PsiPackageCommentFactory.from(psiDirectory);
|
||||
}
|
||||
|
||||
if (node instanceof PsiMethodNode) {
|
||||
// On Show Members
|
||||
PsiMethod psiMethod = ((PsiMethodNode) node).getValue();
|
||||
return PsiMethodCommentFactory.from(psiMethod);
|
||||
}
|
||||
if (node instanceof PsiFieldNode) {
|
||||
// On Show Members
|
||||
PsiField psiField = ((PsiFieldNode) node).getValue();
|
||||
return psiField.getDocComment();
|
||||
}
|
||||
|
||||
if (node instanceof ClassTreeNode) {
|
||||
// On Packages View, Project Files View, Show Members
|
||||
PsiClass psiClass = ((ClassTreeNode) node).getValue();
|
||||
return psiClass.getDocComment();
|
||||
}
|
||||
if (node instanceof PackageElementNode) {
|
||||
// On Packages View
|
||||
PsiPackage psiPackage = ((PackageElementNode) node).getValue().getPackage();
|
||||
return PsiPackageCommentFactory.from(psiPackage);
|
||||
}
|
||||
|
||||
// On Packages View, Project Files View
|
||||
VirtualFile virtualFile = node.getVirtualFile();
|
||||
if (virtualFile == null || !virtualFile.isDirectory()) {
|
||||
return null;
|
||||
}
|
||||
PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(virtualFile);
|
||||
if (psiDirectory == null) {
|
||||
return null;
|
||||
}
|
||||
return PsiPackageCommentFactory.from(psiDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) {
|
||||
// not need
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.github.linwancen.plugin.comment.settings;
|
||||
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
import com.intellij.util.ui.FormBuilder;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class AppSettingsComponent {
|
||||
|
||||
private final JPanel myMainPanel;
|
||||
private final JBCheckBox showTreeComment = new JBCheckBox("Show tree comment ");
|
||||
private final JBCheckBox showLineEndComment = new JBCheckBox("Show line end comment ");
|
||||
|
||||
public AppSettingsComponent() {
|
||||
JPanel comment = FormBuilder.createFormBuilder()
|
||||
.addComponent(showTreeComment, 1)
|
||||
.addComponent(showLineEndComment, 1)
|
||||
.addComponentFillVertically(new JPanel(), 0)
|
||||
.getPanel();
|
||||
comment.setBorder(IdeBorderFactory.createTitledBorder("Comment"));
|
||||
|
||||
myMainPanel = FormBuilder.createFormBuilder()
|
||||
.addComponent(comment, 1)
|
||||
.addComponentFillVertically(new JPanel(), 0)
|
||||
.getPanel();
|
||||
}
|
||||
|
||||
public JPanel getPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return showTreeComment;
|
||||
}
|
||||
|
||||
public boolean getShowTreeComment() {
|
||||
return showTreeComment.isSelected();
|
||||
}
|
||||
|
||||
public void setShowTreeComment(boolean newStatus) {
|
||||
showTreeComment.setSelected(newStatus);
|
||||
}
|
||||
|
||||
public boolean getShowLineEndComment() {
|
||||
return showLineEndComment.isSelected();
|
||||
}
|
||||
|
||||
public void setShowLineEndComment(boolean newStatus) {
|
||||
showLineEndComment.setSelected(newStatus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package io.github.linwancen.plugin.comment.settings;
|
||||
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class AppSettingsConfigurable implements Configurable {
|
||||
|
||||
private AppSettingsComponent mySettingsComponent;
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Title)
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Show Comment.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return mySettingsComponent.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
mySettingsComponent = new AppSettingsComponent();
|
||||
return mySettingsComponent.getPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
AppSettingsState settings = AppSettingsState.getInstance();
|
||||
boolean modified = mySettingsComponent.getShowTreeComment() != settings.showTreeComment;
|
||||
modified |= mySettingsComponent.getShowLineEndComment() != settings.showLineEndComment;
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
AppSettingsState settings = AppSettingsState.getInstance();
|
||||
settings.showTreeComment = mySettingsComponent.getShowTreeComment();
|
||||
settings.showLineEndComment = mySettingsComponent.getShowLineEndComment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
AppSettingsState settings = AppSettingsState.getInstance();
|
||||
mySettingsComponent.setShowTreeComment(settings.showTreeComment);
|
||||
mySettingsComponent.setShowLineEndComment(settings.showLineEndComment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
mySettingsComponent = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.github.linwancen.plugin.comment.settings;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@State(
|
||||
name = "io.github.linwancen.plugin.comment.settings.AppSettingsState",
|
||||
storages = @Storage("ShowCommentPlugin.xml")
|
||||
)
|
||||
public class AppSettingsState implements PersistentStateComponent<AppSettingsState> {
|
||||
|
||||
public boolean showLineEndComment = true;
|
||||
public boolean showTreeComment = true;
|
||||
|
||||
public static AppSettingsState getInstance() {
|
||||
return ApplicationManager.getApplication().getService(AppSettingsState.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AppSettingsState getState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(@NotNull AppSettingsState state) {
|
||||
XmlSerializerUtil.copyBean(state, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CommentFactory {
|
||||
|
||||
private CommentFactory() {}
|
||||
|
||||
public static PsiDocComment fromSrcOrByteCode(PsiDocCommentOwner psiElement) {
|
||||
PsiElement navElement = psiElement.getNavigationElement();
|
||||
if (navElement instanceof PsiDocCommentOwner) {
|
||||
psiElement = (PsiDocCommentOwner) navElement;
|
||||
}
|
||||
return psiElement.getDocComment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment from(PsiFile psiFile) {
|
||||
if (!(psiFile instanceof PsiJavaFile)) {
|
||||
return null;
|
||||
}
|
||||
PsiJavaFile psiJavaFile = (PsiJavaFile) psiFile;
|
||||
if (PsiPackage.PACKAGE_INFO_FILE.equals(psiFile.getName())) {
|
||||
return PsiPackageCommentFactory.fromPackageInfoFile(psiFile);
|
||||
}
|
||||
PsiClass[] classes = psiJavaFile.getClasses();
|
||||
if (classes.length == 0) {
|
||||
return null;
|
||||
}
|
||||
PsiClass psiClass = classes[0];
|
||||
return fromSrcOrByteCode(psiClass);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.psi.javadoc.PsiInlineDocTag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PsiDocCommentUtils {
|
||||
|
||||
private PsiDocCommentUtils() {}
|
||||
|
||||
@Nullable
|
||||
public static String getCommentText(@Nullable PsiDocComment psiDocComment) {
|
||||
if (psiDocComment == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> comments = new ArrayList<>();
|
||||
PsiElement[] elements = psiDocComment.getDescriptionElements();
|
||||
for (PsiElement element : elements) {
|
||||
if (element instanceof PsiDocToken) {
|
||||
PsiDocToken psiDocToken = (PsiDocToken) element;
|
||||
comments.add(psiDocToken.getText());
|
||||
} else if (element instanceof PsiInlineDocTag) {
|
||||
PsiInlineDocTag psiInlineDocTag = (PsiInlineDocTag) element;
|
||||
PsiElement[] children = psiInlineDocTag.getChildren();
|
||||
if (children.length > 2) {
|
||||
comments.add(children[2].getText());
|
||||
}
|
||||
}
|
||||
if (comments.size() > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (comments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(comments.get(0).trim());
|
||||
if (sb.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (comments.size() > 1) {
|
||||
sb.append(" ").append(comments.get(1).trim().replace("<br>", ""));
|
||||
}
|
||||
sb.insert(0, " ");
|
||||
sb.append(" ");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiMethodCommentFactory {
|
||||
|
||||
private PsiMethodCommentFactory() {}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment from(PsiMethod psiMethod) {
|
||||
// .class
|
||||
PsiElement navElement = psiMethod.getNavigationElement();
|
||||
if (navElement instanceof PsiMethod) {
|
||||
psiMethod = (PsiMethod) navElement;
|
||||
}
|
||||
|
||||
PsiDocComment docComment = psiMethod.getDocComment();
|
||||
if (docComment != null) {
|
||||
return docComment;
|
||||
}
|
||||
|
||||
// supper
|
||||
PsiDocComment superDoc = supperMethodComment(psiMethod);
|
||||
if (superDoc != null) {
|
||||
return superDoc;
|
||||
}
|
||||
|
||||
// get/set/is - PropertyDescriptor getReadMethod() getWriteMethod()
|
||||
return propMethodComment(psiMethod, psiMethod.getContainingClass());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment supperMethodComment(PsiMethod psiMethod) {
|
||||
PsiMethod[] superMethods = psiMethod.findSuperMethods();
|
||||
for (PsiMethod superMethod : superMethods) {
|
||||
PsiDocComment superDoc = from(superMethod);
|
||||
if (superDoc != null) {
|
||||
return superDoc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment propMethodComment(PsiMethod psiMethod, PsiClass psiClass) {
|
||||
if (psiClass == null) {
|
||||
return null;
|
||||
}
|
||||
String name = psiMethod.getName();
|
||||
if (name.length() > 3 && (name.startsWith("get") || name.startsWith("set"))) {
|
||||
name = name.substring(3);
|
||||
} else if (name.length() > 2 && name.startsWith("is")) {
|
||||
name = name.substring(2);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
char[] chars = name.toCharArray();
|
||||
chars[0] += 32;
|
||||
name = String.valueOf(chars);
|
||||
PsiField fieldByName = psiClass.findFieldByName(name, false);
|
||||
if (fieldByName == null) {
|
||||
return null;
|
||||
}
|
||||
return fieldByName.getDocComment();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiPackageCommentFactory {
|
||||
|
||||
private PsiPackageCommentFactory() {}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment from(PsiPackage psiPackage) {
|
||||
PsiDirectory[] psiDirectories = psiPackage.getDirectories();
|
||||
for (PsiDirectory psiDirectory : psiDirectories) {
|
||||
PsiDocComment psiDocComment = from(psiDirectory);
|
||||
if (psiDocComment != null) {
|
||||
return psiDocComment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment from(PsiDirectory psiDirectory) {
|
||||
PsiFile packageInfoFile = psiDirectory.findFile(PsiPackage.PACKAGE_INFO_FILE);
|
||||
return fromPackageInfoFile(packageInfoFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiDocComment fromPackageInfoFile(PsiFile packageInfoFile) {
|
||||
if (packageInfoFile == null) {
|
||||
return null;
|
||||
}
|
||||
ASTNode astNode = packageInfoFile.getNode();
|
||||
if (astNode == null) {
|
||||
return null;
|
||||
}
|
||||
ASTNode docCommentNode = findRelevantCommentNode(astNode);
|
||||
if (docCommentNode == null) {
|
||||
return null;
|
||||
}
|
||||
return (PsiDocComment) docCommentNode;
|
||||
}
|
||||
|
||||
private static ASTNode findRelevantCommentNode(@NotNull ASTNode fileNode) {
|
||||
ASTNode node = fileNode.findChildByType(JavaElementType.PACKAGE_STATEMENT);
|
||||
if (node == null) node = fileNode.getLastChildNode();
|
||||
while (node != null && node.getElementType() != JavaDocElementType.DOC_COMMENT) {
|
||||
node = node.getTreePrev();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
|
||||
public class SkipUtils {
|
||||
|
||||
private SkipUtils() {}
|
||||
|
||||
public static boolean skip(PsiClass psiClass) {
|
||||
if (psiClass == null) {
|
||||
return true;
|
||||
}
|
||||
String name = psiClass.getQualifiedName();
|
||||
return name == null || name.startsWith("java");
|
||||
}
|
||||
}
|
||||
37
src/main/resources/META-INF/plugin.xml
Normal file
37
src/main/resources/META-INF/plugin.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<idea-plugin>
|
||||
<id>io.github.linwancen.show-comment</id>
|
||||
<name>Show Comment</name>
|
||||
<vendor email="1498425439@qq.com" url="https://github.com/LinWanCen/show-comment">林万程</vendor>
|
||||
|
||||
<description><![CDATA[
|
||||
English Note:
|
||||
<ul>
|
||||
<li>Show javadoc comments for calling methods at the end of the line.
|
||||
<li>Show javadoc comments in the Project view Tree structure.
|
||||
</ul>
|
||||
Chinese Note:
|
||||
<ul>
|
||||
<li>在行末显示调用方法的文档注释。
|
||||
<li>在结构树显示文档注释。
|
||||
</ul>
|
||||
]]></description>
|
||||
|
||||
<!-- please see https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html
|
||||
on how to target different products -->
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
<depends>com.intellij.modules.java</depends>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<editor.linePainter implementation="io.github.linwancen.plugin.comment.LineEnd" />
|
||||
<projectViewNodeDecorator implementation="io.github.linwancen.plugin.comment.Tree"/>
|
||||
|
||||
<applicationConfigurable parentId="tools"
|
||||
instance="io.github.linwancen.plugin.comment.settings.AppSettingsConfigurable"
|
||||
id="io.github.linwancen.plugin.comment.settings.AppSettingsConfigurable"
|
||||
displayName="Show Comment"/>
|
||||
<applicationService serviceImplementation="io.github.linwancen.plugin.comment.settings.AppSettingsState"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
Reference in New Issue
Block a user