From 879d61e34a09e010995c2d6c8147006b61065cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E4=B8=87=E7=A8=8B?= <1498425439@qq.com> Date: Wed, 6 Apr 2022 23:08:03 +0800 Subject: [PATCH] =?UTF-8?q?1.12=20=20=20=E2=98=85=20=20External=20Comment?= =?UTF-8?q?=20for=20COBOL=20etc=20|=20=E5=A4=96=E9=83=A8=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=20COBOL=20=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 71 ++- build.gradle | 16 +- settings-offline.gradle | 29 ++ .../linwancen/plugin/show/JsonJump.java | 4 +- .../github/linwancen/plugin/show/LineEnd.java | 26 +- .../io/github/linwancen/plugin/show/Tree.java | 56 ++- .../plugin/show/doc/DocTextUtils.java | 45 +- .../plugin/show/ext/DocMapUtils.java | 38 ++ .../plugin/show/ext/LineExtUtils.java | 105 +++++ .../plugin/show/ext/TreeExtUtils.java | 29 ++ .../plugin/show/ext/conf/ConfCache.java | 144 ++++++ .../show/ext/conf/ConfCacheGetUtils.java | 111 +++++ .../plugin/show/ext/conf/ConfFactory.java | 98 +++++ .../show/ext/conf/ConfFileChangeListener.java | 23 + .../show/ext/conf/ConfFileInitListener.java | 17 + .../show/ext/conf/ConfFileListener.java | 64 +++ .../show/ext/conf/ReloadExtDocAction.java | 20 + .../show/line/LineDocRightToLeftUtils.java | 30 +- .../show/settings/AppSettingsState.java | 5 +- .../show/settings/ProjectSettingsState.java | 7 +- src/main/resources/META-INF/plugin.xml | 59 ++- .../cobol/%em%/COBOL-compute-word.cbl.key.tsv | 27 ++ .../ext/cobol/%em%/COBOL-compute.cbl.key.tsv | 6 + .../ext/cobol/%mo/COBOL-accept.cbl.doc.tsv | 6 + .../ext/cobol/%mo/COBOL-accept.cbl.key.tsv | 3 + .../demo/ext/cobol/%mo/COBOL-loop.cbl.key.tsv | 22 + .../ext/cobol/%mo/COBOL-string.cbl.key.tsv | 31 ++ .../demo/ext/cobol/COBOL-file.tsv.tree.tsv | 20 + .../demo/ext/cobol/COBOL-struct.cbl.doc.tsv | 18 + .../show/demo/ext/cobol/COBOL.cbl.key.tsv | 29 ++ .../plugin/show/demo/ext/cobol/COBOL_IDEA.md | 33 ++ .../show/demo/ext/cobol/COBOL_keyword1.md | 410 ++++++++++++++++++ .../cobol/de%/COBOL-data-layout.cbl.key.tsv | 10 + .../ext/cobol/de%/COBOL-data-type.cbl.key.tsv | 15 + .../demo/ext/cobol/de%/COBOL-data.cbl.key.tsv | 5 + .../show/demo/ext/cobol/demo/ACCEPT.cbl | 6 + .../plugin/show/demo/ext/cobol/demo/BASE.cbl | 9 + .../show/demo/ext/cobol/demo/COMPUTE.cbl | 10 + .../plugin/show/demo/ext/cobol/demo/LOOP.cbl | 9 + .../show/demo/ext/cobol/demo/STRUCT.cbl | 22 + .../show/demo/ext/cobol/doc/cbl.doc.tsv | 9 + .../show/demo/ext/cobol/doc/cbl.key.tsv | 1 + .../show/demo/ext/cobol/doc/file.cbl.tree.tsv | 5 + .../show/demo/ext/cobol/doc/file.tsv.tree.tsv | 4 + .../show/demo/ext/cobol/folder.tsv.tree.tsv | 6 + 45 files changed, 1625 insertions(+), 88 deletions(-) create mode 100644 settings-offline.gradle create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/DocMapUtils.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/LineExtUtils.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/TreeExtUtils.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCache.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCacheGetUtils.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFactory.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileChangeListener.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileInitListener.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileListener.java create mode 100644 src/main/java/io/github/linwancen/plugin/show/ext/conf/ReloadExtDocAction.java create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute-word.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.doc.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-loop.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-string.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-file.tsv.tree.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-struct.cbl.doc.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL_IDEA.md create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL_keyword1.md create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-layout.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-type.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data.cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/ACCEPT.cbl create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/BASE.cbl create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/COMPUTE.cbl create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/LOOP.cbl create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/STRUCT.cbl create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.doc.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.key.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.cbl.tree.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.tsv.tree.tsv create mode 100644 src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/folder.tsv.tree.tsv diff --git a/README.md b/README.md index c920095..b7618c2 100644 --- a/README.md +++ b/README.md @@ -3,47 +3,94 @@ IDEA 智能注释插件 https://plugins.jetbrains.com/plugin/18553-show-comment -English Notes: + + +## Notes 说明 + +

English Notes:

-Chinese Notes: + +

External Comment:

+ + + +

中文说明:

-English Change Notes: +

外部注释:

+ + + +## Change Notes 更新说明 + +

English Change Notes:

+ -Chinese Change Notes: +

中文更新说明:

\ No newline at end of file + + + + +### Demo 示例 + +See in IDEA with this plugin | 安装插件后用 IDEA 查看 + +- [Java Doc Comment Demo | Java 文档注释](src/test/java/io/github/linwancen/plugin/show/demo/java/Call.java) +- [JSON Doc Comment Demo | JSON 文档注释](src/test/java/io/github/linwancen/plugin/show/demo/json/base Pojo.json) +- [External Comment Demo For COBOL | 外部注释 Demo](src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/BASE.cbl) + [COBOL Highlighting | COBOL 高亮配置](src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL_IDEA.md) \ No newline at end of file diff --git a/build.gradle b/build.gradle index 09e857a..d787acf 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'io.github.linwancen' -version '1.11.0.' + (new Date().format('yyyy.MM.dd_HH.mm')) +version '1.12.0.' + (new Date().format('yyyy.MM.dd_HH.mm')) apply plugin: 'java' @@ -37,32 +37,34 @@ patchPluginXml { sinceBuild = '201.1' untilBuild = '' changeNotes = """ -English Change Notes: +

English Change Notes:

-Chinese Change Notes: +

中文更新说明:

diff --git a/settings-offline.gradle b/settings-offline.gradle new file mode 100644 index 0000000..68699c0 --- /dev/null +++ b/settings-offline.gradle @@ -0,0 +1,29 @@ +// gradle/init.d/init.gradle use allprojects { +// settings.gradle use pluginManagement { +pluginManagement { + repositories { + all { ArtifactRepository repo -> + if (repo instanceof MavenArtifactRepository) { + def url = repo.url.toString() + if (url.startsWith("https://repo1.maven.org/maven2") + || url.startsWith("https://jcenter.bintray.com/") + || url.startsWith("https://cache-redirector.jetbrains.com")) { + project.logger.lifecycle("remove Repository ${repo.url}.") + remove(repo) + } + } + } + mavenLocal() + maven { name "jetbrains-cache"; url "" } + maven { name "maven-cache"; url "" } + } + buildscript { + repositories { + mavenLocal() + maven { name "jetbrains-cache"; url "" } + } + } +} + +rootProject.name = 'show-comment' + diff --git a/src/main/java/io/github/linwancen/plugin/show/JsonJump.java b/src/main/java/io/github/linwancen/plugin/show/JsonJump.java index be56091..eb87627 100644 --- a/src/main/java/io/github/linwancen/plugin/show/JsonJump.java +++ b/src/main/java/io/github/linwancen/plugin/show/JsonJump.java @@ -13,7 +13,9 @@ import io.github.linwancen.plugin.show.json.JsonRef; import io.github.linwancen.plugin.show.json.JsonUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class JsonJump extends PsiReferenceContributor { diff --git a/src/main/java/io/github/linwancen/plugin/show/LineEnd.java b/src/main/java/io/github/linwancen/plugin/show/LineEnd.java index 3aeecf5..1ab8ec5 100644 --- a/src/main/java/io/github/linwancen/plugin/show/LineEnd.java +++ b/src/main/java/io/github/linwancen/plugin/show/LineEnd.java @@ -14,6 +14,7 @@ import com.intellij.psi.javadoc.PsiDocComment; import io.github.linwancen.plugin.show.doc.DocTextUtils; import io.github.linwancen.plugin.show.line.LineDocLeftToRightUtils; import io.github.linwancen.plugin.show.line.LineDocRightToLeftUtils; +import io.github.linwancen.plugin.show.ext.LineExtUtils; import io.github.linwancen.plugin.show.settings.AppSettingsState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,20 +34,23 @@ public class LineEnd extends EditorLinePainter { if (DumbService.isDumb(project)) { return null; } - FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file); - PsiDocComment docComment = doc(project, viewProvider, lineNumber); - String comment = DocTextUtils.text(docComment); - if (comment == null) { + if (!file.exists()) { + return null; + } + String doc = doc(project, file, lineNumber); + if (doc == null) { return null; } TextAttributes textAttr = file.getFileType().equals(JsonFileType.INSTANCE) ? settings.lineEndJsonTextAttr : settings.lineEndTextAttr; - LineExtensionInfo info = new LineExtensionInfo(settings.lineEndPrefix + comment, textAttr); + LineExtensionInfo info = new LineExtensionInfo(settings.lineEndPrefix + doc, textAttr); return Collections.singletonList(info); } - private static @Nullable PsiDocComment doc(Project project, FileViewProvider viewProvider, int lineNumber) { + private static @Nullable String doc(@NotNull Project project, + @NotNull VirtualFile file, int lineNumber) { + FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file); if (viewProvider == null) { return null; } @@ -63,9 +67,13 @@ public class LineEnd extends EditorLinePainter { if (startOffset == endOffset) { return null; } - if (AppSettingsState.getInstance().findElementRightToLeft) { - return LineDocRightToLeftUtils.rightDoc(viewProvider, startOffset, endOffset); + String ext = LineExtUtils.extDoc(project, file, document, startOffset, endOffset); + if (ext != null) { + return ext; } - return LineDocLeftToRightUtils.leftDoc(viewProvider, document, startOffset, endOffset); + PsiDocComment docComment = AppSettingsState.getInstance().findElementRightToLeft + ? LineDocRightToLeftUtils.rightDoc(viewProvider, startOffset, endOffset) + : LineDocLeftToRightUtils.leftDoc(viewProvider, document, startOffset, endOffset); + return DocTextUtils.text(docComment); } } diff --git a/src/main/java/io/github/linwancen/plugin/show/Tree.java b/src/main/java/io/github/linwancen/plugin/show/Tree.java index 73b0b7c..b0e2e5e 100644 --- a/src/main/java/io/github/linwancen/plugin/show/Tree.java +++ b/src/main/java/io/github/linwancen/plugin/show/Tree.java @@ -5,6 +5,7 @@ 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.application.ApplicationManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -15,6 +16,7 @@ import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import io.github.linwancen.plugin.show.doc.DocTextUtils; import io.github.linwancen.plugin.show.doc.DocUtils; +import io.github.linwancen.plugin.show.ext.TreeExtUtils; import io.github.linwancen.plugin.show.settings.AppSettingsState; import org.jetbrains.annotations.Nullable; @@ -34,25 +36,43 @@ public class Tree implements ProjectViewNodeDecorator { if (DumbService.isDumb(project)) { return; } - - PsiDocComment docComment = nodeDoc(node, project); - if (docComment == null) { - return; - } - - String commentText = DocTextUtils.text(docComment); - if (commentText == null) { - return; - } - List coloredText = data.getColoredText(); - if (coloredText.isEmpty()) { - data.addText(data.getPresentableText(), SimpleTextAttributes.REGULAR_ATTRIBUTES); - } - data.addText(commentText, SimpleTextAttributes.GRAY_ATTRIBUTES); + ApplicationManager.getApplication().runReadAction(() -> { + String doc = doc(node, project); + if (doc == null) { + return; + } + List coloredText = data.getColoredText(); + if (coloredText.isEmpty()) { + data.addText(data.getPresentableText(), SimpleTextAttributes.REGULAR_ATTRIBUTES); + } + data.addText(doc, SimpleTextAttributes.GRAY_ATTRIBUTES); + }); } @Nullable - private PsiDocComment nodeDoc(ProjectViewNode node, Project project) { + private String doc(ProjectViewNode node, Project project) { + String extDoc = extDoc(node, project); + if (extDoc != null) { + return extDoc; + } + PsiDocComment docComment = nodeDoc(node, project); + if (docComment == null) { + return null; + } + return DocTextUtils.text(docComment); + } + + @Nullable + public static String extDoc(ProjectViewNode node, Project project) { + VirtualFile file = node.getVirtualFile(); + if (file == null) { + return null; + } + return TreeExtUtils.extDoc(project, file); + } + + @Nullable + private static PsiDocComment nodeDoc(ProjectViewNode node, Project project) { if (node instanceof PsiFileNode) { PsiFile psiFile = ((PsiFileNode) node).getValue(); return DocUtils.fileDoc(psiFile); @@ -97,7 +117,7 @@ public class Tree implements ProjectViewNodeDecorator { } @Nullable - private PsiDocComment dirDoc(PsiDirectory child) { + private static PsiDocComment dirDoc(PsiDirectory child) { while (true) { PsiDocComment docComment = DocUtils.dirDoc(child); if (docComment != null) { @@ -115,7 +135,7 @@ public class Tree implements ProjectViewNodeDecorator { } @Nullable - private PsiDocComment packageDoc(PsiPackage child) { + private static PsiDocComment packageDoc(PsiPackage child) { while (true) { PsiDocComment docComment = DocUtils.packageDoc(child); if (docComment != null) { diff --git a/src/main/java/io/github/linwancen/plugin/show/doc/DocTextUtils.java b/src/main/java/io/github/linwancen/plugin/show/doc/DocTextUtils.java index 2ed7b26..10ceab9 100644 --- a/src/main/java/io/github/linwancen/plugin/show/doc/DocTextUtils.java +++ b/src/main/java/io/github/linwancen/plugin/show/doc/DocTextUtils.java @@ -7,9 +7,6 @@ import com.intellij.psi.javadoc.PsiInlineDocTag; import io.github.linwancen.plugin.show.settings.AppSettingsState; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - public class DocTextUtils { private DocTextUtils() {} @@ -20,30 +17,40 @@ public class DocTextUtils { return null; } AppSettingsState appSettings = AppSettingsState.getInstance(); - List comments = new ArrayList<>(); + int lineCount = 0; + StringBuilder sb = new StringBuilder(); 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 (appendElementText(sb, element)) { + lineCount++; } - if (appSettings.lineEndCount > 0 && comments.size() >= appSettings.lineEndCount) { + if (appSettings.lineEndCount > 0 + && lineCount >= appSettings.lineEndCount + || appSettings.lineEndLen > 0 + && sb.length() >= appSettings.lineEndLen) { break; } } - if (comments.isEmpty()) { + if (sb.length() == 0) { return null; } - StringBuilder sb = new StringBuilder(" "); - for (String s : comments) { - sb.append(s.trim().replace("
", "")).append(" "); - } + sb.insert(0, " "); return sb.toString(); } + + private static boolean appendElementText(StringBuilder sb, PsiElement element) { + if (element instanceof PsiDocToken) { + PsiDocToken psiDocToken = (PsiDocToken) element; + sb.append(psiDocToken.getText().trim().replace("
", "")).append(" "); + return true; + } + if (element instanceof PsiInlineDocTag) { + PsiInlineDocTag psiInlineDocTag = (PsiInlineDocTag) element; + PsiElement[] children = psiInlineDocTag.getChildren(); + if (children.length > 2) { + sb.append(children[2].getText().trim().replace("
", "")).append(" "); + } + } + return false; + } } diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/DocMapUtils.java b/src/main/java/io/github/linwancen/plugin/show/ext/DocMapUtils.java new file mode 100644 index 0000000..f99dcb8 --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/DocMapUtils.java @@ -0,0 +1,38 @@ +package io.github.linwancen.plugin.show.ext; + +import io.github.linwancen.plugin.show.settings.ProjectSettingsState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +class DocMapUtils { + + private DocMapUtils() {} + + @Nullable + static String get(@NotNull Map>> docMap, + @NotNull ProjectSettingsState set, @NotNull String... words) { + List keywordDoc = list(docMap, words); + if (keywordDoc.size() >= set.extDocColumn) { + return keywordDoc.get(set.extDocColumn - 1); + } + return null; + } + + @NotNull + private static List list(@NotNull Map>> docMap, @NotNull String... words) { + for (Map.Entry>> entry : docMap.entrySet()) { + Map> map = entry.getValue(); + for (String word : words) { + List wordDoc = map.get(word); + if (wordDoc != null) { + return wordDoc; + } + } + } + return Collections.emptyList(); + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/LineExtUtils.java b/src/main/java/io/github/linwancen/plugin/show/ext/LineExtUtils.java new file mode 100644 index 0000000..8c78c73 --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/LineExtUtils.java @@ -0,0 +1,105 @@ +package io.github.linwancen.plugin.show.ext; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import io.github.linwancen.plugin.show.ext.conf.ConfCache; +import io.github.linwancen.plugin.show.settings.ProjectSettingsState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LineExtUtils { + + private LineExtUtils() {} + + public static String extDoc(@NotNull Project project, @NotNull VirtualFile file, + @NotNull Document document, int startOffset, int endOffset) { + Map>> keyMap = ConfCache.keyMap(project, file); + if (keyMap.isEmpty()) { + return null; + } + Pattern pattern = ConfCache.pattern(project, file, keyMap); + if (pattern == null || pattern.pattern().length() == 0) { + return null; + } + Map>> docMap = ConfCache.docMap(project, file); + if (docMap.isEmpty()) { + return null; + } + Map>> treeMap = ConfCache.treeMap(project, file); + String text = document.getText(new TextRange(startOffset, endOffset)); + String[] words = pattern.split(text); + Matcher matcher = pattern.matcher(text); + return extDoc(keyMap, matcher, docMap, words, treeMap, project); + } + + @Nullable + private static String extDoc(@NotNull Map>> keyMap, @NotNull Matcher matcher, + @NotNull Map>> docMap, @NotNull String[] words, + @NotNull Map>> treeMap, @NotNull Project project) { + ProjectSettingsState set = ProjectSettingsState.getInstance(project); + Pattern extReplaceToSpace = set.extReplaceToSpace; + boolean isReplaceToSpace = extReplaceToSpace.pattern().length() != 0; + boolean haveDoc = false; + StringBuilder sb = new StringBuilder(); + for (String s : words) { + if (appendDoc(set, sb, docMap, treeMap, extReplaceToSpace, isReplaceToSpace, s)) { + haveDoc = true; + } + appendKeyDoc(set, sb, keyMap, matcher); + } + if (!haveDoc) { + return null; + } + return sb.toString(); + } + + private static boolean appendDoc(ProjectSettingsState set, StringBuilder sb, + @NotNull Map>> docMap, + @NotNull Map>> treeMap, + Pattern extReplaceToSpace, boolean isReplaceToSpace, String word) { + word = word.trim(); + if (isReplaceToSpace) { + word = extReplaceToSpace.matcher(word).replaceAll(" "); + } + if (word.length() == 0) { + return false; + } + String wordDoc = DocMapUtils.get(docMap, set, word); + if (wordDoc != null) { + sb.append(wordDoc); + return true; + } + String treeDoc = DocMapUtils.get(treeMap, set, word); + if (treeDoc != null) { + sb.append(treeDoc); + return true; + } + sb.append(word); + return false; + } + + private static void appendKeyDoc(@NotNull ProjectSettingsState set, @NotNull StringBuilder sb, + @NotNull Map>> keyMap, + @NotNull Matcher matcher) { + if (!matcher.find()) { + return; + } + String keyword = matcher.group(); + // "" if no doc + String keyDoc = DocMapUtils.get(keyMap, set, keyword); + if (keyDoc != null) { + sb.append(" ").append(keyDoc); + } + // no one space + if (sb.length() != 1) { + sb.append(" "); + } + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/TreeExtUtils.java b/src/main/java/io/github/linwancen/plugin/show/ext/TreeExtUtils.java new file mode 100644 index 0000000..a11205a --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/TreeExtUtils.java @@ -0,0 +1,29 @@ +package io.github.linwancen.plugin.show.ext; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import io.github.linwancen.plugin.show.ext.conf.ConfCache; +import io.github.linwancen.plugin.show.settings.ProjectSettingsState; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Map; + +public class TreeExtUtils { + + private TreeExtUtils() {} + + public static String extDoc(@NotNull Project project, @NotNull VirtualFile file) { + Map>> docMap = ConfCache.treeMap(project, file); + ProjectSettingsState set = ProjectSettingsState.getInstance(project); + String[] words = { + file.getName(), + file.getNameWithoutExtension(), + }; + String extDoc = DocMapUtils.get(docMap, set, words); + if (extDoc == null) { + return null; + } + return " " + extDoc; + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCache.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCache.java new file mode 100644 index 0000000..3fc5196 --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCache.java @@ -0,0 +1,144 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.intellij.notification.NotificationDisplayType; +import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.search.FilenameIndex; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; + +/** + * call ConfFactory, ConfCacheGetUtils + */ +public class ConfCache { + + private static final Pattern LINE_PATTERN = Pattern.compile("[\\r\\n]++"); + + static final String EXT = "tsv"; + static final String KEY_MID_EXT = ".key"; + static final String DOC_MID_EXT = ".doc"; + static final String TREE_MID_EXT = ".tree"; + + private static final Map>> KEY_CACHE = new ConcurrentHashMap<>(); + private static final Map>> DOC_CACHE = new ConcurrentHashMap<>(); + private static final Map>> TREE_CACHE = new ConcurrentHashMap<>(); + + private ConfCache() {} + + @Nullable + public static Pattern pattern(@Nullable Project project, @NotNull VirtualFile file, + @NotNull Map>> keyMap) { + return ConfFactory.buildPattern(project, file.getPath(), keyMap); + } + + @NotNull + public static Map>> keyMap(@Nullable Project project, @NotNull VirtualFile file) { + return ConfCacheGetUtils.get(file, KEY_MID_EXT, KEY_CACHE); + } + + @NotNull + public static Map>> docMap(@Nullable Project project, @NotNull VirtualFile file) { + return ConfCacheGetUtils.get(file, DOC_MID_EXT, DOC_CACHE); + } + + @NotNull + public static Map>> treeMap(@Nullable Project project, @NotNull VirtualFile file) { + return ConfCacheGetUtils.get(file, TREE_MID_EXT, TREE_CACHE); + } + + static void remove(@NotNull VirtualFile file, String name) { + if (name != null) { + int i = name.lastIndexOf('.'); + name = name.substring(0, i); + } else { + name = file.getNameWithoutExtension(); + } + if (name.endsWith(KEY_MID_EXT)) { + KEY_CACHE.remove(file); + } else if (name.endsWith(DOC_MID_EXT)) { + DOC_CACHE.remove(file); + } else if (name.endsWith(TREE_MID_EXT)) { + TREE_CACHE.remove(file); + } + } + + static void copy(@NotNull VirtualFile file, @NotNull VirtualFile newFile) { + String name = file.getNameWithoutExtension(); + if (name.endsWith(KEY_MID_EXT)) { + copyCache(file, newFile, KEY_CACHE); + } else if (name.endsWith(DOC_MID_EXT)) { + copyCache(file, newFile, DOC_CACHE); + } else if (name.endsWith(TREE_MID_EXT)) { + copyCache(file, newFile, TREE_CACHE); + } + } + + private static void copyCache(@Nullable VirtualFile file, @NotNull VirtualFile newFile, + @NotNull Map>> cache) { + Map> map = cache.get(file); + if (map != null) { + cache.put(newFile, new LinkedHashMap<>(map)); + } + } + + private static final NotificationGroup LOAD_ALL_LOG = + new NotificationGroup("Ext Doc Conf Load All", NotificationDisplayType.BALLOON, true); + + static void loadAll(@NotNull Project project) { + ApplicationManager.getApplication().runReadAction(() -> + DumbService.getInstance(project).runReadActionInSmartMode(() -> { + Collection files = FilenameIndex.getAllFilesByExt(project, EXT); + StringBuilder sb = new StringBuilder(); + KEY_CACHE.clear(); + DOC_CACHE.clear(); + TREE_CACHE.clear(); + for (VirtualFile file : files) { + load(project, file); + sb.append(file.getPath()).append("\n"); + } + if (files.isEmpty()) { + return; + } + LOAD_ALL_LOG.createNotification("Ext doc conf load all complete", files.size() + " files", + sb.toString(), NotificationType.INFORMATION).notify(project); + })); + } + + static void loadFile(@Nullable Project project, @NotNull VirtualFile file) { + ApplicationManager.getApplication().runReadAction(() -> ConfCache.load(project, file)); + } + + private static void load(@Nullable Project project, @NotNull VirtualFile file) { + if (!ConfCache.EXT.equals(file.getExtension())) { + return; + } + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document == null) { + return; + } + String text = document.getText(); + String name = file.getNameWithoutExtension(); + // this pattern would skip empty line + String[] lines = LINE_PATTERN.split(text); + if (name.endsWith(KEY_MID_EXT)) { + KEY_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, true)); + } else if (name.endsWith(DOC_MID_EXT)) { + DOC_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, false)); + } else if (name.endsWith(TREE_MID_EXT)) { + TREE_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, false)); + } + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCacheGetUtils.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCacheGetUtils.java new file mode 100644 index 0000000..285604d --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfCacheGetUtils.java @@ -0,0 +1,111 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.intellij.openapi.vfs.VirtualFile; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.TreeMap; + +class ConfCacheGetUtils { + + private static final String SKIP_PATH = "doc"; + private static final String MATCH_STR = "%"; + + private ConfCacheGetUtils() {} + + /** + *
file: + *
a/b/c.ext + *
+ *
configure file priority: + *
a/b/c.ext.key.tsv + *
a/b/x.c.ext.key.tsv + *
a/b/ext.key.tsv + *
a/b/x.ext.key.tsv + *
a/c.ext.key.tsv + * + * @return {@code } + */ + @NotNull + static TreeMap get(@NotNull VirtualFile file, + @NotNull String confMidExt, + @NotNull Map cache) { + String path = file.getPath(); + String name = file.getName(); + String ext = file.getExtension(); + if (ext == null) { + ext = ""; + } + TreeMap map = new TreeMap<>(); + int max = path.length(); + int length = String.valueOf(max).length(); + for (Map.Entry entry : cache.entrySet()) { + VirtualFile confFile = entry.getKey(); + String confName = confFile.getNameWithoutExtension(); + String confPath = confFile.getPath(); + int level = level(path, confPath); + if (level == 0) { + continue; + } + String levelStr = StringUtils.leftPad(String.valueOf(max - level), length, '0'); + if ((name + confMidExt).equals(confName)) { + map.put(levelStr + "\b" + confPath, entry.getValue()); + } else if (confName.endsWith((name + confMidExt))) { + map.put(levelStr + "\t" + confPath, entry.getValue()); + } else if ((ext + confMidExt).equals(confName)) { + map.put(levelStr + "\n" + confPath, entry.getValue()); + } else if (confName.endsWith((ext + confMidExt))) { + map.put(levelStr + "\f" + confPath, entry.getValue()); + } + } + return map; + } + + private static int level(String path, String confPath) { + path = srcPath(path); + confPath = srcPath(confPath); + String[] paths = StringUtils.split(path, '/'); + String[] confPaths = StringUtils.split(confPath, '/'); + int length = confPaths.length; + if (length > paths.length) { + return 0; + } + for (int i = 0; i < length; i++) { + if (!match(paths[i], confPaths[i])) { + return i; + } + } + return length; + } + + @NotNull + private static String srcPath(String path) { + int i = path.indexOf('!'); + if (i != -1) { + return path.substring(i + 1); + } + i = path.indexOf("/resources"); + if (i != -1) { + return path.substring(i + "/resources".length()); + } + return path; + } + + private static boolean match(String path, String confPath) { + if (confPath.equals(path) || SKIP_PATH.equals(confPath)) { + return true; + } + boolean end = false; + boolean start = false; + if (confPath.startsWith(MATCH_STR)) { + confPath = confPath.substring(1); + end = true; + } + if (confPath.endsWith(MATCH_STR)) { + confPath = confPath.substring(0, confPath.length() - 1); + start = true; + } + return end && path.endsWith(confPath) || start && path.startsWith(confPath); + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFactory.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFactory.java new file mode 100644 index 0000000..6e544ad --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFactory.java @@ -0,0 +1,98 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.google.common.base.Splitter; +import com.intellij.notification.NotificationDisplayType; +import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.project.Project; +import com.twelvemonkeys.util.LinkedSet; +import groovy.json.StringEscapeUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; + +class ConfFactory { + + private static final Pattern EMPTY_PATTERN = Pattern.compile(""); + private static final Map PATTERN_CACHE = new ConcurrentHashMap<>(); + private static final NotificationGroup REGEXP_LOG = + new NotificationGroup("Ext Doc Keyword Regexp Compile", NotificationDisplayType.TOOL_WINDOW, true); + private static final NotificationGroup DATA_LOG = + new NotificationGroup("Ext Doc Data", NotificationDisplayType.BALLOON, true); + + private ConfFactory() {} + + @Nullable + static Pattern buildPattern(@Nullable Project project, @NotNull String path, + @NotNull Map>> map) { + Set exclude = new LinkedSet<>(); + StringBuilder sb = new StringBuilder(); + for (Map> keyMap : map.values()) { + // key() is escape + for (List list : keyMap.values()) { + String key = list.get(0); + if (key.startsWith("?")) { + exclude.add(key.substring(1)); + } else if (key.length() > 0 && !exclude.contains(key)) { + sb.append(key).append("|"); + } + } + } + if (sb.length() > 0) { + sb.delete(sb.length() - 1, sb.length()); + } + String regex = sb.toString(); + Pattern pattern = PATTERN_CACHE.get(regex); + if (pattern != null) { + return pattern; + } + sb.insert(0, "\n"); + sb.insert(0, path); + sb.insert(0, "\n"); + try { + Pattern compile = Pattern.compile(regex); + PATTERN_CACHE.put(regex, compile); + REGEXP_LOG.createNotification("Ext doc keyword regexp compile success", regex.length() + " chars", + sb.toString(), NotificationType.INFORMATION).notify(project); + return compile; + } catch (Exception e) { + sb.insert(0, "\n"); + sb.insert(0, e.getLocalizedMessage()); + PATTERN_CACHE.put(regex, EMPTY_PATTERN); + REGEXP_LOG.createNotification("Ext doc keyword regexp compile fail", regex.length() + " chars", + sb.toString(), NotificationType.ERROR).notify(project); + return null; + } + } + + public static final Pattern DEL_PATTERN = Pattern.compile("\\(\\?[^)]++\\)"); + + @NotNull + static Map> buildMap(@Nullable Project project, @NotNull String path, + @NotNull String[] lines, boolean isKey) { + Map> map = new LinkedHashMap<>(); + for (String line : lines) { + List words = Splitter.on('\t').splitToList(line); + if (!words.isEmpty()) { + String key = words.get(0); + if (key.length() == 0) { + continue; + } + if (isKey) { + key = StringEscapeUtils.unescapeJava(key); + String del = DEL_PATTERN.matcher(key).replaceAll(""); + if (del.length() != 0) { + key = del; + } + } + map.put(key, words); + } + } + DATA_LOG.createNotification("Ext doc file load complete", map.size() + " lines", + "\n" + path, NotificationType.INFORMATION).notify(project); + return map; + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileChangeListener.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileChangeListener.java new file mode 100644 index 0000000..fc802a8 --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileChangeListener.java @@ -0,0 +1,23 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.intellij.openapi.fileEditor.FileEditorManagerEvent; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * call ConfCache.loadFile + */ +public class ConfFileChangeListener implements FileEditorManagerListener { + + @Override + public void selectionChanged(@NotNull FileEditorManagerEvent event) { + VirtualFile file = event.getOldFile(); + if (file == null) { + return; + } + if (file.exists()) { + ConfCache.loadFile(event.getManager().getProject(), file); + } + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileInitListener.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileInitListener.java new file mode 100644 index 0000000..2f67883 --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileInitListener.java @@ -0,0 +1,17 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManagerListener; +import org.jetbrains.annotations.NotNull; + +/** + * call ConfCache.loadAll + */ +public class ConfFileInitListener implements ProjectManagerListener { + + @Override + public void projectOpened(@NotNull Project project) { + ConfCache.loadAll(project); + } + +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileListener.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileListener.java new file mode 100644 index 0000000..a5cde1f --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ConfFileListener.java @@ -0,0 +1,64 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.BulkFileListener; +import com.intellij.openapi.vfs.newvfs.events.*; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * call ConfCache.loadFile, copy, remove + */ +public class ConfFileListener implements BulkFileListener { + + @Override + public void after(@NotNull List events) { + for (VFileEvent event : events) { + forEvent(event); + } + } + + private static void forEvent(VFileEvent event) { + VirtualFile file = event.getFile(); + if (file == null) { + return; + } + if (event instanceof VFilePropertyChangeEvent) { + VFilePropertyChangeEvent changeEvent = (VFilePropertyChangeEvent) event; + if ("name".equals(changeEvent.getPropertyName())) { + String oldName = changeEvent.getOldValue().toString(); + if (oldName.endsWith(ConfCache.EXT)) { + // change cache too complicated so remove + ConfCache.remove(file, oldName); + } + } + } + if (!ConfCache.EXT.equals(file.getExtension())) { + return; + } + if (event instanceof VFileMoveEvent) { + return; + } + if (event instanceof VFileDeleteEvent) { + ConfCache.remove(file, null); + return; + } + if (event instanceof VFileCopyEvent) { + VFileCopyEvent copyEvent = (VFileCopyEvent) event; + VirtualFile newFile = copyEvent.findCreatedFile(); + if (newFile == null) { + return; + } + try { + ConfCache.copy(file, newFile); + } catch (Exception ignored) { + // ignore + } + return; + } + // VFileCreateEvent + // VFileContentChangeEvent + ConfCache.loadFile(null, file); + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/ext/conf/ReloadExtDocAction.java b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ReloadExtDocAction.java new file mode 100644 index 0000000..4272c72 --- /dev/null +++ b/src/main/java/io/github/linwancen/plugin/show/ext/conf/ReloadExtDocAction.java @@ -0,0 +1,20 @@ +package io.github.linwancen.plugin.show.ext.conf; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** + * call ConfCache.loadAll + */ +public class ReloadExtDocAction extends AnAction { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + Project project = e.getProject(); + if (project == null) { + return; + } + ConfCache.loadAll(project); + } +} diff --git a/src/main/java/io/github/linwancen/plugin/show/line/LineDocRightToLeftUtils.java b/src/main/java/io/github/linwancen/plugin/show/line/LineDocRightToLeftUtils.java index 54cdccf..20ac8ea 100644 --- a/src/main/java/io/github/linwancen/plugin/show/line/LineDocRightToLeftUtils.java +++ b/src/main/java/io/github/linwancen/plugin/show/line/LineDocRightToLeftUtils.java @@ -19,24 +19,18 @@ public class LineDocRightToLeftUtils { // End is always white, can not -1 because @see class.name need it PsiElement element = viewProvider.findElementAt(endOffset); if (element == null) { + // one line end return null; } - AppSettingsState instance = AppSettingsState.getInstance(); - PsiElement identifier; - PsiDocComment psiDocComment; + AppSettingsState setting = AppSettingsState.getInstance(); while (true) { - identifier = PsiTreeUtil.prevVisibleLeaf(element); + PsiElement identifier = PsiTreeUtil.prevVisibleLeaf(element); if (identifier != null && identifier.getTextRange().getStartOffset() < startOffset) { identifier = null; } - if (identifier == null || identifier instanceof PsiIdentifier) { - if (instance.inJson && element.getLanguage().is(JsonLanguage.INSTANCE)) { - return JsonDocUtils.jsonDoc(element, startOffset, endOffset); - } - psiDocComment = LineDocUtils.elementDoc(element, identifier, startOffset, endOffset); - if (psiDocComment != null) { - return psiDocComment; - } + PsiDocComment docComment = psiDoc(setting, identifier, element, startOffset, endOffset); + if (docComment != null) { + return docComment; } if (identifier == null) { return null; @@ -44,4 +38,16 @@ public class LineDocRightToLeftUtils { element = identifier; } } + + public static PsiDocComment psiDoc(AppSettingsState setting, + PsiElement identifier, PsiElement element, + int startOffset, int endOffset) { + if (identifier != null && !(identifier instanceof PsiIdentifier)) { + return null; + } + if (setting.inJson && element.getLanguage().is(JsonLanguage.INSTANCE)) { + return JsonDocUtils.jsonDoc(element, startOffset, endOffset); + } + return LineDocUtils.elementDoc(element, identifier, startOffset, endOffset); + } } diff --git a/src/main/java/io/github/linwancen/plugin/show/settings/AppSettingsState.java b/src/main/java/io/github/linwancen/plugin/show/settings/AppSettingsState.java index 0444af4..59fba7c 100644 --- a/src/main/java/io/github/linwancen/plugin/show/settings/AppSettingsState.java +++ b/src/main/java/io/github/linwancen/plugin/show/settings/AppSettingsState.java @@ -22,9 +22,9 @@ public class AppSettingsState implements PersistentStateComponent林万程 English Notes:
  • Show javadoc comments at the Project view Tree structure
  • Show javadoc comments at the end-of-line
  • Show javadoc comments at "xx ClassNameOrSimpleName.json" and jump to field -
  • Config: settings -> Tools -> Show Comment Global/Project +
  • Config: settings -> Tools -> // Show Comment Global/Project
-Chinese Notes: + +

External Comment:

+
    +
  • Reload: Tools -> 🔄 // Reload External Comment +
  • path/[any][filename.]ext.tree.tsv // file and folder tree comment 📝 📁 +
  • path/[any][filename.]ext.key.tsv // line keywords to split and comment +
  • path/[any][filename.]ext.doc.tsv // line words comment +
  • In path, "doc" can replace any, and can use % like in SQL +
  • The line in key.tsv would concat lines with `|` to regexp, longer str should in front, startWith `?` to exclude +
  • Chang tsv file in find pop window would not reload! +
  • The tsv conf file must could be search in "Go to File"(Ctrl + Shift + N) +
+ + +

中文说明:

  • 在结构树显示 文档注释
  • 在行末尾显示 文档注释
  • 支持 "xx 类全名或简名.json" 文档注释与跳转到字段 -
  • 修改配置:设置 -> 工具 -> Show Comment Global/Project +
  • 修改配置:设置 -> 工具 -> // Show Comment Global/Project +
+ +

外部注释:

+
    +
  • 重新加载:工具 -> "🔄 // Reload External Comment" +
  • path/[any][filename.]ext.tree.tsv // 文件(夹)注释 📝 📁 +
  • path/[any][filename.]ext.key.tsv // 切割关键字与注释 +
  • path/[any][filename.]ext.doc.tsv // 词注释 +
  • key.tsv 的每一行将会用`|`连接起来形成正则表达式,较长的关键字应该放在前面,用 `?` 开头排除 +
  • doc 文件夹可以替换任何一层文件夹,可以像 SQL 那样用 % 模糊匹配 +
  • 在搜索弹出窗中修改 tsv 文件将不会被重加载 +
  • tsv 配置文件必须能被搜索(Ctrl + Shift + N)
]]>
@@ -25,6 +51,21 @@ Chinese Notes: com.intellij.modules.platform com.intellij.modules.java + + + + + + + + + + + + @@ -32,18 +73,24 @@ Chinese Notes: + displayName="// Show Comment Global"/> + displayName="// Show Comment Project"/> + + + \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute-word.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute-word.cbl.key.tsv new file mode 100644 index 0000000..90ce387 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute-word.cbl.key.tsv @@ -0,0 +1,27 @@ + COBOL 算数词汇【关键字】 + ADD/SUBTRACT CORR WS-GROUP1 TO WS-GROUP2 // 数组间很少用 + GIVING => + + ADD A B TO C D // C = A + B + C; D = A + B + D + ADD A B C TO D GIVING E // E = A + B + C + D + TO 是基本关键字 => 这里忽略 + ADD + + + + SUBTRACT A B FROM C D // C = C - (A + B); D = D - (A + B) + SUBTRACT A B C FROM D GIVING E // E = D - (A + B + C) + SUBTRACT - + FROM 从 + + + MULTIPLY A BY B C // B = A * B; C = A * C + MULTIPLY A BY B GIVING C // C = A * B + MULTIPLY * + BY by + + + DIVIDE A INTO B // B = B / A; + DIVIDE A BY B GIVING C REMAINDER D // C = A / B ... D + DIVIDE ÷ + INTO 从 + REMAINDER 余 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute.cbl.key.tsv new file mode 100644 index 0000000..5a610e5 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%em%/COBOL-compute.cbl.key.tsv @@ -0,0 +1,6 @@ + COBOL 算数符号【关键字】 + COMPUTE + \+ + + \- - + \* * + \/ / \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.doc.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.doc.tsv new file mode 100644 index 0000000..008bc65 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.doc.tsv @@ -0,0 +1,6 @@ + COBOL 获取词汇(非必要) +DATE 系统日期 +DATE YYYYMMDD 系统日期 +TIME 系统时间 +SYSIN 系统输入 +CONSOLE 控制台 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.key.tsv new file mode 100644 index 0000000..d5b246c --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-accept.cbl.key.tsv @@ -0,0 +1,3 @@ + COBOL 获取【关键字】(非必要) + ACCEPT 获取 + FROM 从 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-loop.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-loop.cbl.key.tsv new file mode 100644 index 0000000..1059533 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-loop.cbl.key.tsv @@ -0,0 +1,22 @@ + COBOL 循环【关键字】(非必要) + + PERFORM HELLO-WORLD THRU STRUCT + THRU ~ + + PERFORM A-PARA UNTIL COUNT=5 + PERFORM A-PARA WITH TEST BEFORE UNTIL COUNT=5 + PERFORM A-PARA WITH TEST AFTER UNTIL COUNT=5 + UNTIL until + COUNT count + WITH TEST BEFORE before + WITH TEST AFTER after + + + PERFORM A-PARA 5 TIMES. +(?=\d++ TIMES) + + PERFORM A-PARA VARYING A FROM 1 BY 1 UNTIL A=5 + VARYING varying + + GO TO para-1 para-2 para-3 DEPENDING ON x. + DEPENDING ON switch \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-string.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-string.cbl.key.tsv new file mode 100644 index 0000000..e60f523 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/%mo/COBOL-string.cbl.key.tsv @@ -0,0 +1,31 @@ + COBOL 字符串【关键字】(非必要) + + INSPECT input-string + TALLYING output-count FOR ALL CHARACTERS + INSPECT + TALLYING + FOR ALL CHARACTERS + + + INSPECT input-string REPLACING ALL char1 BY char2. + REPLACING + + + STRING ws-string1 DELIMITED BY SPACE + ws-string2 DELIMITED BY SIZE + INTO ws-destination-string + WITH POINTER ws-count + ON OVERFLOW DISPLAY message1 + NOT ON OVERFLOW DISPLAY message2 + END-STRING. + STRING + DELIMITED + BY by + + + UNSTRING ws-string DELIMITED BY SPACE + INTO ws-str1, ws-str2 + WITH POINTER ws-count + ON OVERFLOW DISPLAY message + NOT ON OVERFLOW DISPLAY message + END-UNSTRING. diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-file.tsv.tree.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-file.tsv.tree.tsv new file mode 100644 index 0000000..7b50aea --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-file.tsv.tree.tsv @@ -0,0 +1,20 @@ +COBOL-file.tsv.tree.tsv 📝 COBOL 相关文件注释 + +COBOL.cbl.key.tsv COBOL 必要【关键字】 + +COBOL-struct.cbl.doc.tsv COBOL 文件结构【关键字】 + +COBOL-data.cbl.key.tsv COBOL 数据部必要【关键字】 +COBOL-data-layout.cbl.key.tsv COBOL 数据布局【关键字】 +COBOL-data-type.cbl.key.tsv COBOL 数据类型【关键字】 + +COBOL-compute.cbl.key.tsv COBOL 算数符号【关键字】 +COBOL-compute-word.cbl.key.tsv COBOL 算数词汇【关键字】 + +COBOL-accept.cbl.doc.tsv COBOL 获取词汇(非必要) +COBOL-accept.cbl.key.tsv COBOL 获取【关键字】(非必要) +COBOL-loop.cbl.key.tsv COBOL 循环【关键字】(非必要) +COBOL-string.cbl.key.tsv COBOL 字符串【关键字】(非必要) + +COBOL_IDEA.md COBOL IDEA 高亮设置 +COBOL_keyword1.md COBOL COBOL IDEA 高亮 普通关键字 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-struct.cbl.doc.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-struct.cbl.doc.tsv new file mode 100644 index 0000000..47bea81 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL-struct.cbl.doc.tsv @@ -0,0 +1,18 @@ + COBOL 文件结构【关键字】 + +IDENTIFICATION DIVISION 【标识部】 + +ENVIRONMENT DIVISION 【环境部】 +SOURCE-COMPUTER (编译系统) +OBJECT-COMPUTER (执行系统) +CONFIGURATION SECTION [配置节] +INPUT-OUTPUT SECTION [输入输出节] +FILE-CONTROL (外部数据集) + +DATA DIVISION 【数据部】 +FILE SECTION [文件节] +WORKING-STORAGE SECTION [工作存储节] +LOCAL-STORAGE SECTION [本地存储节] +LINKAGE SECTION [连接节] + +PROCEDURE DIVISION 【过程部】 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL.cbl.key.tsv new file mode 100644 index 0000000..35a2a62 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL.cbl.key.tsv @@ -0,0 +1,29 @@ + COBOL 必要【关键字】 + key 文件的注释前面要有制表符 + 长的要放在短的前面 + +^.{7} +\. . +\, , + + INITIALIZE 初始化 + MOVE + TO => + + IF if + 有些程序 THEN 没有换行所以要加这个关键字 + THEN + NOT(?! '| ?=) ! + AND (?!') && + OR (?!') || + + 兼容单字符字典 +\=(?! ?') = +> > +< < + + PERFORM call + WS- + +(? Settings -> Editor -> File Types +- 文件 -> 设置 -> 编辑器 -> 文件类型 + +## Syntax Highlighting + +Line comment: * + +## Keywords + +
+1 blue 蓝色 +
+ +[关键字1列表](COBOL_keyword1.md) + +
+2 Purple 紫色
+END-IF
+IF
+THEN
+
+ +
+3 cyanogen 青色
+INITIALIZE
+
+ +
+4 brown 褐色
+PERFORM
+
diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL_keyword1.md b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL_keyword1.md new file mode 100644 index 0000000..4b40391 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/COBOL_keyword1.md @@ -0,0 +1,410 @@ +SET +TO +VARYING +ACCEPT +ACCESS +ADD +ADDRESS +ADVANCING +AFTER +ALL +ALPHABET +ALPHABETIC +ALPHABETIC-LOWER +ALPHABETIC-UPPER +ALPHANUMERIC +ALPHANUMERIC-EDITED +ALSO +ALTER +ALTERNATE +AND +ANY +APPLY +ARE +AREA +AREAS +ASCENDING +ASSIGN +AT +AUTHOR +BASIS +BEFORE +BEGINNING +BINARY +BLANK +BLOCK +BOTTOM +BY +CALL +CANCEL +CBL +CD +CF +CH +CHARACTER +CHARACTERS +CLASS +CLASS-ID +CLOCK-UNITS +CLOSE +COBOL +CODE +CODE-SET +COLLATING +COLUMN +COM-REG +COMMA +COMMON +COMMUNICATION +COMP +COMP-1 +COMP-2 +COMP-3 +COMP-4 +COMP-5 +COMPUTATIONAL +COMPUTATIONAL-1 +COMPUTATIONAL-2 +COMPUTATIONAL-3 +COMPUTATIONAL-4 +COMPUTATIONAL-5 +COMPUTE +CONFIGURATION +CONTAINS +CONTENT +CONTINUE +CONTROL +CONTROLS +CONVERTING +COPY +CORR +CORRESPONDING +COUNT +CURRENCY +DATA +DATE-COMPILED +DATE-WRITTEN +DAY +DAY-OF-WEEK +DBCS +DE +DEBUG-CONTENTS +DEBUG-ITEM +DEBUG-LINE +DEBUG-NAME +DEBUG-SUB-1 +DEBUG-SUB-2 +DEBUG-SUB-3 +DEBUGGING +DECIMAL-POINT +DECLARATIVES +DELETE +DELIMITED +DELIMITER +DEPENDING +DESCENDING +DESTINATION +DETAIL +DISPLAY +DISPLAY-1 +DIVIDE +DIVISION +DOWN +DUPLICATES +DYNAMIC +EGCS +EGI +EJECT +ELSE +EMI +ENABLE +END +END-ADD +END-CALL +END-COMPUTE +END-DELETE +END-DIVIDE +END-EVALUATE + +END-INVOKE +END-MULTIPLY +END-OF-PAGE +END-PERFORM +END-READ +END-RECEIVE +END-RETURN +END-REWRITE +END-SEARCH +END-START +END-STRING +END-SUBTRACT +END-UNSTRING +END-WRITE +ENDING +ENTER +ENTRY +ENVIRONMENT +EOP +EQUAL +ERROR +ESI +EVALUATE +EVERY +EXCEPTION +EXIT +EXTEND +EXTERNAL +FALSE +FD +FILE +FILE-CONTROL +FILLER +FINAL +FIRST +FOOTING +FOR +FROM +FUNCTION +GENERATE +GIVING +GLOBAL +GO +GOBACK +GREATER +GROUP +HEADINHIGH-VALUHIGH-VALUES +I-O +I-O-CONTROL +ID +IDENTIFICATION + +IN +INDEX +INDEXED +INDICATE +INHERITS +INITIAL + +INITIATE +INPUT +INPUT-OUTPUT +INSERT +INSPECT +INSTALLATION +INTO +INVALID +INVOKE +IS +JUSJUSTIFIE +KANJKE +LABEL +LAST +LEADING +LEFT +LENGTH +LESS +LIMIT +LIMITS +LINAGE +LINAGE-COUNTER +LINE +LINE-COUNTER +LINES +LINKAGE +LOCAL-STORAGE +LOCK +LOW-VALUE +LOW-VALUES +MEMORY +MERGE +MESSAGE +METACLASS +METHOD +METHOD-ID +MODE +MODULES +MORE-LABELS +MOVE +MULTIPLE +MULTIPLY +NATIVE +NATIVE_BINARY +NEGATIVE +NEXT +NO +NOT +NULL +NULLS +NUMBER +NUMERIC +NUMERIC-EDITED +OBJECT +OBJECT-COMPUTER +OCCURS +OF +OFF +OMITTED +ON +OPEN +OPTIONAL +OR +ORDER +ORGANIZATION +OTHER +OUTPUT +OVERFLOW +OVERRIDE +PACKED-DECIMAL +PADDING +PAGE +PAGE-COUNTER +PASSWORD + +PF +PH +PIC +PICTURE +PLUS +POINTER +POSITION +POSITIVE +PRINTING +PROCEDURE +PROCEDURE-POINTER +PROCEDURES +PROCEED +PROCESSING +PROGRAM +PROGRAM-ID +PURGE +QUEUQUOTQUOTES +RANDOM +RD +READ +READY +RECEIVE +RECORD +RECORDING +RECORDS +RECURSIVE +REDEFINES +REEL +REFERENCE +REFERENCES +RELATIVE +RELEASE +RELOAD +REMAINDER +REMOVAL +RENAMES +REPLACE +REPLACING +REPORT +REPORTING +REPORTS +REPOSITORY +RERUN +RESERVE +RESET +RETURN +RETURN-CODE +RETURNING +REVERSED +REWIND +REWRITE +RF +RH +RIGHT +ROUNDED +RUN +SAME +SD +SEARCH +SECTION +SECURITY +SEGMENT +SEGMENT-LIMIT +SELECT +SELF +SEND +SENTENCE +SEPARATE +SEQUENCE +SEQUENTIAL +SERVICE +SET +SHIFT-IN +SHIFT-OUT +SIGN +SIZE +SKIP1 +SKIP2 +SKIP3 +SORT +SORT-CONTROL +SORT-CORE-SIZE +SORT-FILE-SIZE +SORT-MERGE +SORT-MESSAGE +SORT-MODE-SIZE +SORT-RETURN +SOURCE +SOURCE-COMPUTER +SPACE +SPACES +SPECIAL-NAMES +STANDARD +STANDARD-1 +STANDARD-2 +START +STATUS +STOP +STRING +SUB-QUEUE-1 +SUB-QUEUE-2 +SUB-QUEUE-3 +SUBTRACT +SUM +SUPER +SUPPRESS +SYMBOLIC +SYNC +SYNCHRONIZED +TABLE +TALLY +TALLYING +TAPE +TERMINAL +TERMINATE +TEST +TEXT +THAN + +THROUGH +THRU +TIME +TIMES +TITLE +TO +TOP +TRACE +TRAILING +TRUE +TYPE +UNIT +UNSTRING +UNTIL +UP +UPON +USAGE +USE +USING +VALUVALUEVARYING +WHEN +WHEN-COMPILED +WITH +WORDS +WORKING-STORAGE +WRITE +WRITE-ONLY +ZERZEROEZEROS \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-layout.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-layout.cbl.key.tsv new file mode 100644 index 0000000..a856626 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-layout.cbl.key.tsv @@ -0,0 +1,10 @@ + COBOL 数据布局【关键字】 + + REDEFINES 重定义 + RENAMES 重命名 + USAGE IS + COMP 二进制整数 + COMP-1 单精度浮点 + COMP-2 双精度浮点 + COMP-3 压缩十进制 + COPY \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-type.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-type.cbl.key.tsv new file mode 100644 index 0000000..0e1cc6c --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data-type.cbl.key.tsv @@ -0,0 +1,15 @@ + COBOL 数据类型【关键字】 + + 66 重命名 + 77 不能被细分项 + 88 条件名 + +9\( ( 数字 +A\( ( 字母 +X\( ( 字母数字 +V\( ( 隐式小数 +S\( ( 符号 +P\( ( 假定小数 + + 数据 + VALUE = \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data.cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data.cbl.key.tsv new file mode 100644 index 0000000..dcb8c25 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/de%/COBOL-data.cbl.key.tsv @@ -0,0 +1,5 @@ + COBOL 数据部必要【关键字】 +^.{7} +\d{2} + PIC + COPY + REPLACING \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/ACCEPT.cbl b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/ACCEPT.cbl new file mode 100644 index 0000000..b414e81 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/ACCEPT.cbl @@ -0,0 +1,6 @@ + + ACCEPT HELLO-WORLD FROM DATE + ACCEPT HELLO-WORLD FROM DATE YYYYMMDD + ACCEPT HELLO-WORLD FROM TIME + ACCEPT HELLO-WORLD FROM SYSIN + ACCEPT HELLO-WORLD FROM CONSOLE \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/BASE.cbl b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/BASE.cbl new file mode 100644 index 0000000..75e2074 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/BASE.cbl @@ -0,0 +1,9 @@ + +123456 INITIALIZE HELLO-WORLD + IF KEY = '1' AND KEY NOT = '2' AND (B OR NOT C) THEN + MOVE WS-HELLO-WORLD TO HELLO-WORLD + END IF + TABLE(STRUCT) + HELLO-WORLD(1:1) + PERFORM B001-A + * PERFORM STRUCT \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/COMPUTE.cbl b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/COMPUTE.cbl new file mode 100644 index 0000000..a781717 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/COMPUTE.cbl @@ -0,0 +1,10 @@ + + COMPUTE HELLO-WORLD = (A - B) * 100 / (C + D) + END-COMPUTE + ADD A TO B + ADD A B TO C D + SUBTRACT A FROM C + SUBTRACT A B FROM C D + MULTIPLY A BY B C + MULTIPLY A BY B GIVING C + DIVIDE A BY B GIVING C REMAINDER D \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/LOOP.cbl b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/LOOP.cbl new file mode 100644 index 0000000..2d971a0 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/LOOP.cbl @@ -0,0 +1,9 @@ + + PERFORM STRUCT THRU HELLO-WORLD + END-PERFORM. + PERFORM STRUCT UNTIL COUNT=5 + PERFORM STRUCT WITH TEST BEFORE UNTIL COUNT=5 + PERFORM STRUCT WITH TEST AFTER UNTIL COUNT=5 + PERFORM STRUCT 5 TIMES + PERFORM STRUCT VARYING HELLO-WORLD FROM 1 BY 1 UNTIL HELLO-WORLD=5 + GO TO STRUCT DEPENDING ON HELLO-WORLD. \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/STRUCT.cbl b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/STRUCT.cbl new file mode 100644 index 0000000..e584ce9 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/demo/STRUCT.cbl @@ -0,0 +1,22 @@ + + IDENTIFICATION DIVISION. + PROGRAM-ID. STRUCT. + + ENVIRONMENT DIVISION. + SOURCE-COMPUTER. XXX-ZOS. + OBJECT-COMPUTER. XXX-ZOS. + CONFIGURATION SECTION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + + DATA DIVISION. + FILE SECTION. + WORKING-STORAGE SECTION. + 01 WS-HELLO-WORLD PIC X(9) VALUE 10 . + LOCAL-STORAGE SECTION. + 01 HELLO-WORLD PIC X(9) VALUE 10 . + LINKAGE SECTION. + 01 A PIC 9(9) VALUE 10 . + + + PROCEDURE DIVISION. \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.doc.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.doc.tsv new file mode 100644 index 0000000..2fe6d80 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.doc.tsv @@ -0,0 +1,9 @@ +KEY = '1' 字典1 +KEY NOT = '2' 非 字典2 +HELLO-WORLD 你好世界 +B001-A 程序A +A a +B b +C c +D d +HELLO-WORLD(1:1 ( 状态1 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.key.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.key.tsv new file mode 100644 index 0000000..ea0ec7e --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/cbl.key.tsv @@ -0,0 +1 @@ +TABLE\( 表( \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.cbl.tree.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.cbl.tree.tsv new file mode 100644 index 0000000..14de759 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.cbl.tree.tsv @@ -0,0 +1,5 @@ +ACCEPT 获取示例 +BASE 基本示例 +COMPUTE ➗ 计算示例 +LOOP ♻ 循环示例 +STRUCT 结构示例 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.tsv.tree.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.tsv.tree.tsv new file mode 100644 index 0000000..ddb8e4c --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/doc/file.tsv.tree.tsv @@ -0,0 +1,4 @@ +cbl.doc.tsv 自定义注释 +cbl.key.tsv 自定义【关键字】 +file.cbl.tree.tsv 📝 本目录 cbl 文件注释 +file.tsv.tree.tsv 📝 本目录 tsv 文件注释 \ No newline at end of file diff --git a/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/folder.tsv.tree.tsv b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/folder.tsv.tree.tsv new file mode 100644 index 0000000..5eeb7a1 --- /dev/null +++ b/src/test/java/io/github/linwancen/plugin/show/demo/ext/cobol/folder.tsv.tree.tsv @@ -0,0 +1,6 @@ +folder.tsv.tree.tsv 📁 本目录文件夹注释 +demo 📝 示例 +%em% 前后 %s 匹配 +%mo 前 %s 匹配 +de% 后 %s 匹配 +doc doc 匹配 \ No newline at end of file