1.12 ★ External Comment for COBOL etc | 外部注释用于 COBOL 等
This commit is contained in:
71
README.md
71
README.md
@@ -3,47 +3,94 @@ IDEA 智能注释插件
|
||||
|
||||
https://plugins.jetbrains.com/plugin/18553-show-comment
|
||||
|
||||
English Notes:
|
||||
|
||||
|
||||
## Notes 说明
|
||||
|
||||
<h2>English Notes:</h2>
|
||||
<ul>
|
||||
<li>Show javadoc comments at the Project view Tree structure
|
||||
<li>Show javadoc comments at the end-of-line
|
||||
<li>Show javadoc comments at "xx ClassNameOrSimpleName.json" and jump to field
|
||||
<li>Config: settings -> Tools -> Show Comment Global/Project
|
||||
<li>Config: settings -> Tools -> // Show Comment Global/Project
|
||||
</ul>
|
||||
Chinese Notes:
|
||||
|
||||
<h3>External Comment:</h3>
|
||||
<ul>
|
||||
<li>Reload: Tools -> 🔄 // Reload External Comment
|
||||
<li>path/[any][filename.]ext.tree.tsv // file and folder tree comment 📝 📁
|
||||
<li>path/[any][filename.]ext.key.tsv // line keywords to split and comment
|
||||
<li>path/[any][filename.]ext.doc.tsv // line words comment
|
||||
<li>In path, "doc" can replace any, and can use % like in SQL
|
||||
<li>The line in key.tsv would concat lines with `|` to regexp, longer str should in front, startWith `?` to exclude
|
||||
<li>Chang tsv file in find pop window would not reload!
|
||||
<li>The tsv conf file must could be search in "Go to File"(Ctrl + Shift + N)
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>中文说明:</h2>
|
||||
<ul>
|
||||
<li>在结构树显示 文档注释
|
||||
<li>在行末尾显示 文档注释
|
||||
<li>支持 "xx 类全名或简名.json" 文档注释与跳转到字段
|
||||
<li>修改配置:设置 -> 工具 -> Show Comment Global/Project
|
||||
<li>修改配置:设置 -> 工具 -> // Show Comment Global/Project
|
||||
</ul>
|
||||
|
||||
English Change Notes:
|
||||
<h3>外部注释:</h3>
|
||||
<ul>
|
||||
<li>重新加载:工具 -> "🔄 // Reload External Comment"
|
||||
<li>path/[any][filename.]ext.tree.tsv // 文件(夹)注释 📝 📁
|
||||
<li>path/[any][filename.]ext.key.tsv // 切割关键字与注释
|
||||
<li>path/[any][filename.]ext.doc.tsv // 词注释
|
||||
<li>key.tsv 的每一行将会用`|`连接起来形成正则表达式,较长的关键字应该放在前面,用 `?` 开头排除
|
||||
<li>doc 文件夹可以替换任何一层文件夹,可以像 SQL 那样用 % 模糊匹配
|
||||
<li>在搜索弹出窗中修改 tsv 文件将不会被重加载
|
||||
<li>tsv 配置文件必须能被搜索(Ctrl + Shift + N)
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
## Change Notes 更新说明
|
||||
|
||||
<h2>English Change Notes:</h2>
|
||||
<ul>
|
||||
<li>1.12 ★ External Comment for COBOL etc
|
||||
<li>1.11 Add json key jump to field
|
||||
<li>1.10 Add project-view-tree-comment for package from parent or other project
|
||||
<li>1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file
|
||||
<li>1.8 Add line-end-comment for "xx ClassNameOrSimpleName.json"
|
||||
<li>1.8 ★ line-end-comment for "xx ClassNameOrSimpleName.json"
|
||||
<li>1.7 Add line-end-comment setting for prefix and count
|
||||
<li>1.6 Add line-end-comment independent switch for call, new, ref
|
||||
<li>1.5 Add line-end-comment find next loop when none
|
||||
<li>1.4 Add line-end-comment find element right to left
|
||||
<li>1.3 Add project-view-tree-comment
|
||||
<li>1.3 ★ project-view-tree-comment
|
||||
<li>1.2 Add line-end-comment settings fro class prefix filter
|
||||
<li>1.1 Add line-end-comment settings for text color
|
||||
</ul>
|
||||
|
||||
Chinese Change Notes:
|
||||
<h2>中文更新说明:</h2>
|
||||
<ul>
|
||||
<li>1.11 增加 json 跳转到字段
|
||||
<li>1.12 ★ 外部注释用于 COBOL 等
|
||||
<li>1.11 增加 json 跳转到字段
|
||||
<li>1.10 增加 在父包和其他项目的包中获取 项目导航栏注释
|
||||
<li>1.9 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
|
||||
<li>1.8 增加 "xx 类全名或简名.json" 行末注释
|
||||
<li>1.8 ★ "xx 类全名或简名.json" 行末注释
|
||||
<li>1.7 增加 行末注释前缀和对象数设置
|
||||
<li>1.6 增加 行末调用,new,引用注释独立开关
|
||||
<li>1.5 增加 没有注释时循环查找下一个对象
|
||||
<li>1.4 增加 从右往左查找行末注释对象
|
||||
<li>1.3 增加 项目导航栏注释
|
||||
<li>1.3 ★ 项目导航栏注释
|
||||
<li>1.2 增加 行末注释类前缀配置
|
||||
<li>1.1 增加 行末文本颜色配置
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
### 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)
|
||||
16
build.gradle
16
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:
|
||||
<h2>English Change Notes:</h2>
|
||||
<ul>
|
||||
<li>1.12 ★ External Comment for COBOL etc
|
||||
<li>1.11 Add json key jump to field
|
||||
<li>1.10 Add project-view-tree-comment for package from parent or other project
|
||||
<li>1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file
|
||||
<li>1.8 Add line-end-comment for "xx ClassNameOrSimpleName.json"
|
||||
<li>1.8 ★ line-end-comment for "xx ClassNameOrSimpleName.json"
|
||||
<li>1.7 Add line-end-comment setting for prefix and count
|
||||
<li>1.6 Add line-end-comment independent switch for call, new, ref
|
||||
<li>1.5 Add line-end-comment find next loop when none
|
||||
<li>1.4 Add line-end-comment find element right to left
|
||||
<li>1.3 Add project-view-tree-comment
|
||||
<li>1.3 ★ project-view-tree-comment
|
||||
<li>1.2 Add line-end-comment settings fro class prefix filter
|
||||
<li>1.1 Add line-end-comment settings for text color
|
||||
</ul>
|
||||
|
||||
Chinese Change Notes:
|
||||
<h2>中文更新说明:</h2>
|
||||
<ul>
|
||||
<li>1.12 ★ 外部注释用于 COBOL 等
|
||||
<li>1.11 增加 json 跳转到字段
|
||||
<li>1.10 增加 在父包和其他项目的包中获取 项目导航栏注释
|
||||
<li>1.9 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
|
||||
<li>1.8 增加 "xx 类全名或简名.json" 行末注释
|
||||
<li>1.8 ★ "xx 类全名或简名.json" 行末注释
|
||||
<li>1.7 增加 行末注释前缀和对象数设置
|
||||
<li>1.6 增加 行末调用,new,引用注释独立开关
|
||||
<li>1.5 增加 没有注释时循环查找下一个对象
|
||||
<li>1.4 增加 从右往左查找行末注释对象
|
||||
<li>1.3 增加 项目导航栏注释
|
||||
<li>1.3 ★ 项目导航栏注释
|
||||
<li>1.2 增加 行末注释类前缀配置
|
||||
<li>1.1 增加 行末文本颜色配置
|
||||
</ul>
|
||||
|
||||
29
settings-offline.gradle
Normal file
29
settings-offline.gradle
Normal file
@@ -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'
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ColoredFragment> 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<ColoredFragment> 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) {
|
||||
|
||||
@@ -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<String> 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("<br>", "")).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("<br>", "")).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("<br>", "")).append(" ");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, Map<String, List<String>>> docMap,
|
||||
@NotNull ProjectSettingsState set, @NotNull String... words) {
|
||||
List<String> keywordDoc = list(docMap, words);
|
||||
if (keywordDoc.size() >= set.extDocColumn) {
|
||||
return keywordDoc.get(set.extDocColumn - 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> list(@NotNull Map<String, Map<String, List<String>>> docMap, @NotNull String... words) {
|
||||
for (Map.Entry<String, Map<String, List<String>>> entry : docMap.entrySet()) {
|
||||
Map<String, List<String>> map = entry.getValue();
|
||||
for (String word : words) {
|
||||
List<String> wordDoc = map.get(word);
|
||||
if (wordDoc != null) {
|
||||
return wordDoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -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<String, Map<String, List<String>>> 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<String, Map<String, List<String>>> docMap = ConfCache.docMap(project, file);
|
||||
if (docMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Map<String, List<String>>> 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<String, Map<String, List<String>>> keyMap, @NotNull Matcher matcher,
|
||||
@NotNull Map<String, Map<String, List<String>>> docMap, @NotNull String[] words,
|
||||
@NotNull Map<String, Map<String, List<String>>> 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<String, Map<String, List<String>>> docMap,
|
||||
@NotNull Map<String, Map<String, List<String>>> 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<String, Map<String, List<String>>> 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(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String, Map<String, List<String>>> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<VirtualFile, Map<String, List<String>>> KEY_CACHE = new ConcurrentHashMap<>();
|
||||
private static final Map<VirtualFile, Map<String, List<String>>> DOC_CACHE = new ConcurrentHashMap<>();
|
||||
private static final Map<VirtualFile, Map<String, List<String>>> TREE_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private ConfCache() {}
|
||||
|
||||
@Nullable
|
||||
public static Pattern pattern(@Nullable Project project, @NotNull VirtualFile file,
|
||||
@NotNull Map<String, Map<String, List<String>>> keyMap) {
|
||||
return ConfFactory.buildPattern(project, file.getPath(), keyMap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<String, Map<String, List<String>>> keyMap(@Nullable Project project, @NotNull VirtualFile file) {
|
||||
return ConfCacheGetUtils.get(file, KEY_MID_EXT, KEY_CACHE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<String, Map<String, List<String>>> docMap(@Nullable Project project, @NotNull VirtualFile file) {
|
||||
return ConfCacheGetUtils.get(file, DOC_MID_EXT, DOC_CACHE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<String, Map<String, List<String>>> 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<VirtualFile, Map<String, List<String>>> cache) {
|
||||
Map<String, List<String>> 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<VirtualFile> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() {}
|
||||
|
||||
/**
|
||||
* <br>file:
|
||||
* <br>a/b/c.ext
|
||||
* <br>
|
||||
* <br>configure file priority:
|
||||
* <br>a/b/c.ext.key.tsv
|
||||
* <br>a/b/x.c.ext.key.tsv
|
||||
* <br>a/b/ext.key.tsv
|
||||
* <br>a/b/x.ext.key.tsv
|
||||
* <br>a/c.ext.key.tsv
|
||||
*
|
||||
* @return {@code <sortKey, T>}
|
||||
*/
|
||||
@NotNull
|
||||
static <T> TreeMap<String, T> get(@NotNull VirtualFile file,
|
||||
@NotNull String confMidExt,
|
||||
@NotNull Map<VirtualFile, T> cache) {
|
||||
String path = file.getPath();
|
||||
String name = file.getName();
|
||||
String ext = file.getExtension();
|
||||
if (ext == null) {
|
||||
ext = "";
|
||||
}
|
||||
TreeMap<String, T> map = new TreeMap<>();
|
||||
int max = path.length();
|
||||
int length = String.valueOf(max).length();
|
||||
for (Map.Entry<VirtualFile, T> 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);
|
||||
}
|
||||
}
|
||||
@@ -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<String, Pattern> 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<String, Map<String, List<String>>> map) {
|
||||
Set<String> exclude = new LinkedSet<>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map<String, List<String>> keyMap : map.values()) {
|
||||
// key() is escape
|
||||
for (List<String> 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<String, List<String>> buildMap(@Nullable Project project, @NotNull String path,
|
||||
@NotNull String[] lines, boolean isKey) {
|
||||
Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
for (String line : lines) {
|
||||
List<String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<? extends VFileEvent> 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ public class AppSettingsState implements PersistentStateComponent<AppSettingsSta
|
||||
public boolean showTreeComment = true;
|
||||
public boolean showLineEndComment = true;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@SuppressWarnings("UseJBColor")
|
||||
public Color lineEndColorBright = new Color(98, 151, 85);
|
||||
@SuppressWarnings("all")
|
||||
@SuppressWarnings("UseJBColor")
|
||||
public Color lineEndColorDark = new Color(98, 151, 85);
|
||||
public final TextAttributes lineEndTextAttr = new TextAttributes(new JBColor(lineEndColorBright, lineEndColorDark),
|
||||
null, null, null, Font.ITALIC);
|
||||
@@ -34,6 +34,7 @@ public class AppSettingsState implements PersistentStateComponent<AppSettingsSta
|
||||
public boolean findElementRightToLeft = true;
|
||||
public String lineEndPrefix = " //";
|
||||
public int lineEndCount = 2;
|
||||
public int lineEndLen = 0;
|
||||
public boolean fromCall = true;
|
||||
public boolean fromNew = true;
|
||||
public boolean fromRef = true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.github.linwancen.plugin.show.settings;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -9,6 +8,8 @@ import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@State(
|
||||
name = "io.github.linwancen.plugin.comment.settings.ProjectSettingsState",
|
||||
storages = @Storage("ShowCommentProject.xml")
|
||||
@@ -21,9 +22,11 @@ public class ProjectSettingsState implements PersistentStateComponent<ProjectSet
|
||||
public String lineEndExclude = "";
|
||||
public String[] lineEndIncludeArray = {};
|
||||
public String[] lineEndExcludeArray = {};
|
||||
public Pattern extReplaceToSpace = Pattern.compile("");
|
||||
public int extDocColumn = 2;
|
||||
|
||||
public static ProjectSettingsState getInstance(Project project) {
|
||||
return ServiceManager.getService(project, ProjectSettingsState.class);
|
||||
return project.getService(ProjectSettingsState.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -4,19 +4,45 @@
|
||||
<vendor email="1498425439@qq.com" url="https://github.com/LinWanCen/show-comment">林万程</vendor>
|
||||
|
||||
<description><![CDATA[
|
||||
English Notes:
|
||||
<h2>English Notes:</h2>
|
||||
<ul>
|
||||
<li>Show javadoc comments at the Project view Tree structure
|
||||
<li>Show javadoc comments at the end-of-line
|
||||
<li>Show javadoc comments at "xx ClassNameOrSimpleName.json" and jump to field
|
||||
<li>Config: settings -> Tools -> Show Comment Global/Project
|
||||
<li>Config: settings -> Tools -> // Show Comment Global/Project
|
||||
</ul>
|
||||
Chinese Notes:
|
||||
|
||||
<h3>External Comment:</h3>
|
||||
<ul>
|
||||
<li>Reload: Tools -> 🔄 // Reload External Comment
|
||||
<li>path/[any][filename.]ext.tree.tsv // file and folder tree comment 📝 📁
|
||||
<li>path/[any][filename.]ext.key.tsv // line keywords to split and comment
|
||||
<li>path/[any][filename.]ext.doc.tsv // line words comment
|
||||
<li>In path, "doc" can replace any, and can use % like in SQL
|
||||
<li>The line in key.tsv would concat lines with `|` to regexp, longer str should in front, startWith `?` to exclude
|
||||
<li>Chang tsv file in find pop window would not reload!
|
||||
<li>The tsv conf file must could be search in "Go to File"(Ctrl + Shift + N)
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>中文说明:</h2>
|
||||
<ul>
|
||||
<li>在结构树显示 文档注释
|
||||
<li>在行末尾显示 文档注释
|
||||
<li>支持 "xx 类全名或简名.json" 文档注释与跳转到字段
|
||||
<li>修改配置:设置 -> 工具 -> Show Comment Global/Project
|
||||
<li>修改配置:设置 -> 工具 -> // Show Comment Global/Project
|
||||
</ul>
|
||||
|
||||
<h3>外部注释:</h3>
|
||||
<ul>
|
||||
<li>重新加载:工具 -> "🔄 // Reload External Comment"
|
||||
<li>path/[any][filename.]ext.tree.tsv // 文件(夹)注释 📝 📁
|
||||
<li>path/[any][filename.]ext.key.tsv // 切割关键字与注释
|
||||
<li>path/[any][filename.]ext.doc.tsv // 词注释
|
||||
<li>key.tsv 的每一行将会用`|`连接起来形成正则表达式,较长的关键字应该放在前面,用 `?` 开头排除
|
||||
<li>doc 文件夹可以替换任何一层文件夹,可以像 SQL 那样用 % 模糊匹配
|
||||
<li>在搜索弹出窗中修改 tsv 文件将不会被重加载
|
||||
<li>tsv 配置文件必须能被搜索(Ctrl + Shift + N)
|
||||
</ul>
|
||||
]]></description>
|
||||
|
||||
@@ -25,6 +51,21 @@ Chinese Notes:
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
<depends>com.intellij.modules.java</depends>
|
||||
|
||||
<applicationListeners>
|
||||
<listener class="io.github.linwancen.plugin.show.ext.conf.ConfFileListener"
|
||||
topic="com.intellij.openapi.vfs.newvfs.BulkFileListener"/>
|
||||
</applicationListeners>
|
||||
|
||||
<applicationListeners>
|
||||
<listener class="io.github.linwancen.plugin.show.ext.conf.ConfFileChangeListener"
|
||||
topic="com.intellij.openapi.fileEditor.FileEditorManagerListener"/>
|
||||
</applicationListeners>
|
||||
|
||||
<projectListeners>
|
||||
<listener class="io.github.linwancen.plugin.show.ext.conf.ConfFileInitListener"
|
||||
topic="com.intellij.openapi.project.ProjectManagerListener"/>
|
||||
</projectListeners>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<editor.linePainter implementation="io.github.linwancen.plugin.show.LineEnd" />
|
||||
<projectViewNodeDecorator implementation="io.github.linwancen.plugin.show.Tree"/>
|
||||
@@ -32,18 +73,24 @@ Chinese Notes:
|
||||
<applicationConfigurable parentId="tools"
|
||||
instance="io.github.linwancen.plugin.show.settings.AppSettingsConfigurable"
|
||||
id="io.github.linwancen.plugin.show.settings.AppSettingsConfigurable"
|
||||
displayName="Show Comment Global"/>
|
||||
displayName="// Show Comment Global"/>
|
||||
<applicationService serviceImplementation="io.github.linwancen.plugin.show.settings.AppSettingsState"/>
|
||||
|
||||
<projectConfigurable parentId="tools"
|
||||
instance="io.github.linwancen.plugin.show.settings.ProjectSettingsConfigurable"
|
||||
id="io.github.linwancen.plugin.show.settings.ProjectSettingsConfigurable"
|
||||
displayName="Show Comment Project"/>
|
||||
displayName="// Show Comment Project"/>
|
||||
<projectService serviceImplementation="io.github.linwancen.plugin.show.settings.ProjectSettingsState"/>
|
||||
|
||||
<psi.referenceContributor implementation="io.github.linwancen.plugin.show.JsonJump"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
<action
|
||||
id="io.github.linwancen.plugin.show.ext.conf.ReLoadExtDocAction"
|
||||
class="io.github.linwancen.plugin.show.ext.conf.ReloadExtDocAction"
|
||||
text="🔄 // Reload External Comment">
|
||||
<add-to-group group-id="ToolsMenu"/>
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
@@ -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 余
|
||||
|
@@ -0,0 +1,6 @@
|
||||
COBOL 算数符号【关键字】
|
||||
COMPUTE
|
||||
\+ +
|
||||
\- -
|
||||
\* *
|
||||
\/ /
|
||||
|
@@ -0,0 +1,6 @@
|
||||
COBOL 获取词汇(非必要)
|
||||
DATE 系统日期
|
||||
DATE YYYYMMDD 系统日期
|
||||
TIME 系统时间
|
||||
SYSIN 系统输入
|
||||
CONSOLE 控制台
|
||||
|
@@ -0,0 +1,3 @@
|
||||
COBOL 获取【关键字】(非必要)
|
||||
ACCEPT 获取
|
||||
FROM 从
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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 高亮 普通关键字
|
||||
|
@@ -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 【过程部】
|
||||
|
@@ -0,0 +1,29 @@
|
||||
COBOL 必要【关键字】
|
||||
key 文件的注释前面要有制表符
|
||||
长的要放在短的前面
|
||||
|
||||
^.{7}
|
||||
\. .
|
||||
\, ,
|
||||
|
||||
INITIALIZE 初始化
|
||||
MOVE
|
||||
TO =>
|
||||
|
||||
IF if
|
||||
有些程序 THEN 没有换行所以要加这个关键字
|
||||
THEN
|
||||
NOT(?! '| ?=) !
|
||||
AND (?!') &&
|
||||
OR (?!') ||
|
||||
|
||||
兼容单字符字典
|
||||
\=(?! ?') =
|
||||
> >
|
||||
< <
|
||||
|
||||
PERFORM call
|
||||
WS-
|
||||
|
||||
(?<!\w)\( (
|
||||
\) )
|
||||
|
@@ -0,0 +1,33 @@
|
||||
# IDEA COBOL 高亮配置
|
||||
|
||||
- File -> Settings -> Editor -> File Types
|
||||
- 文件 -> 设置 -> 编辑器 -> 文件类型
|
||||
|
||||
## Syntax Highlighting
|
||||
|
||||
Line comment: *
|
||||
|
||||
## Keywords
|
||||
|
||||
<div style="color:#0033B3">
|
||||
1 blue 蓝色
|
||||
</div>
|
||||
|
||||
[关键字1列表](COBOL_keyword1.md)
|
||||
|
||||
<pre style="color:#74118C">
|
||||
2 Purple 紫色
|
||||
END-IF
|
||||
IF
|
||||
THEN
|
||||
</pre>
|
||||
|
||||
<pre style="color:#008080">
|
||||
3 cyanogen 青色
|
||||
INITIALIZE
|
||||
</pre>
|
||||
|
||||
<pre style="color:#800000">
|
||||
4 brown 褐色
|
||||
PERFORM
|
||||
</pre>
|
||||
@@ -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
|
||||
@@ -0,0 +1,10 @@
|
||||
COBOL 数据布局【关键字】
|
||||
|
||||
REDEFINES 重定义
|
||||
RENAMES 重命名
|
||||
USAGE IS
|
||||
COMP 二进制整数
|
||||
COMP-1 单精度浮点
|
||||
COMP-2 双精度浮点
|
||||
COMP-3 压缩十进制
|
||||
COPY
|
||||
|
@@ -0,0 +1,15 @@
|
||||
COBOL 数据类型【关键字】
|
||||
|
||||
66 重命名
|
||||
77 不能被细分项
|
||||
88 条件名
|
||||
|
||||
9\( ( 数字
|
||||
A\( ( 字母
|
||||
X\( ( 字母数字
|
||||
V\( ( 隐式小数
|
||||
S\( ( 符号
|
||||
P\( ( 假定小数
|
||||
|
||||
数据
|
||||
VALUE =
|
||||
|
@@ -0,0 +1,5 @@
|
||||
COBOL 数据部必要【关键字】
|
||||
^.{7} +\d{2}
|
||||
PIC
|
||||
COPY
|
||||
REPLACING
|
||||
|
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
@@ -0,0 +1 @@
|
||||
TABLE\( 表(
|
||||
|
@@ -0,0 +1,5 @@
|
||||
ACCEPT 获取示例
|
||||
BASE 基本示例
|
||||
COMPUTE ➗ 计算示例
|
||||
LOOP ♻ 循环示例
|
||||
STRUCT 结构示例
|
||||
|
@@ -0,0 +1,4 @@
|
||||
cbl.doc.tsv 自定义注释
|
||||
cbl.key.tsv 自定义【关键字】
|
||||
file.cbl.tree.tsv 📝 本目录 cbl 文件注释
|
||||
file.tsv.tree.tsv 📝 本目录 tsv 文件注释
|
||||
|
@@ -0,0 +1,6 @@
|
||||
folder.tsv.tree.tsv 📁 本目录文件夹注释
|
||||
demo 📝 示例
|
||||
%em% 前后 %s 匹配
|
||||
%mo 前 %s 匹配
|
||||
de% 后 %s 匹配
|
||||
doc doc 匹配
|
||||
|
Reference in New Issue
Block a user