2.04 json dict doc from (key).tsv | 从 键名.tsv 中读取 json 的字典注释 fixed #12

This commit is contained in:
林万程
2022-10-30 18:34:23 +08:00
parent 82d0ade99b
commit c6318f88a2
22 changed files with 184 additions and 94 deletions

View File

@@ -1,7 +1,8 @@
# Show Comment Plugin
IDEA 智能注释插件
https://plugins.jetbrains.com/plugin/18553-show-comment
[![Version](https://img.shields.io/jetbrains/plugin/v/io.github.linwancen.show-comment.svg)](https://plugins.jetbrains.com/plugin/io.github.linwancen.show-comment)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/io.github.linwancen.show-comment.svg)](https://plugins.jetbrains.com/plugin/io.github.linwancen.show-comment)
Thanks JetBrains Licenses for Open Source.
@@ -61,6 +62,7 @@ Show doc comment at the Project view Tree, line End, json etc.
<h2>English Change Notes:</h2>
<ul>
<li>2.04 Add line-end-comment json dict doc from (key).tsv
<li>2.03 Add live-templates input `doc` `docc` -> /** */
<li>2.02 Add line-end-comment show before doc for `isA(xxx)` and `a.set(b.get)`
<li>2.01 Add line-end-comment support SQL, JavaScript, Python, Golang, Kotlin
@@ -93,6 +95,7 @@ Show doc comment at the Project view Tree, line End, json etc.
<h2>中文更新说明:</h2>
<ul>
<li>2.04 增加 行末注释 从 键名.tsv 中读取 json 的字典注释
<li>2.03 增加 活动模板 输入 doc / docc 等生成 /** */
<li>2.02 增加 行末注释 `isA(xxx)``a.set(b.get)` 显示前一个注释
<li>2.01 增加 行末注释 支持 SQL, JavaScript, Python, Golang, Kotlin

View File

@@ -4,7 +4,7 @@ plugins {
}
group 'io.github.linwancen'
version '2.03.0.' + (new Date().format('yyyy.MM.dd_HH.mm'))
version '2.04.0.' + (new Date().format('yyyy.MM.dd_HH.mm'))
repositories {
mavenCentral()
@@ -87,6 +87,7 @@ patchPluginXml {
changeNotes = """
<h2>English Change Notes:</h2>
<ul>
<li>2.04 Add line-end-comment json dict doc from (key).tsv
<li>2.03 Add live-templates input `doc` `docc` -> /** */
<li>2.02 Add line-end-comment show before doc for `isA(xxx)` and `a.set(b.get)`
<li>2.01 Add line-end-comment support SQL, JavaScript, Python, Golang, Kotlin
@@ -119,7 +120,8 @@ patchPluginXml {
<h2>中文更新说明:</h2>
<ul>
<li>2.03 增加 活动模板 输入 `doc` `docc` 生成 /** */
<li>2.04 增加 行末注释 从 键名.tsv 中读取 json 的字典注释
<li>2.03 增加 活动模板 输入 doc / docc 等生成 /** */
<li>2.02 增加 行末注释 `isA(xxx)` 和 `a.set(b.get)` 显示前一个注释
<li>2.01 增加 行末注释 支持 SQL, JavaScript, Python, Golang, Kotlin
<li>2.00 ★★ 支持所有 JetBrains 软件

View File

@@ -14,13 +14,19 @@ pluginManagement {
}
}
mavenLocal()
maven { name "jetbrains-cache"; url "" }
maven { name "maven-cache"; url "" }
maven { name "jetbrains-cache"; url ""
// allowInsecureProtocol true // 7.0+
}
maven { name "maven-cache"; url ""
// allowInsecureProtocol true // 7.0+
}
}
buildscript {
repositories {
mavenLocal()
maven { name "jetbrains-cache"; url "" }
maven { name "jetbrains-cache"; url ""
// allowInsecureProtocol true // 7.0+
}
}
}
}

View File

@@ -40,7 +40,7 @@ public class JavaLangDoc extends BaseTagLangDoc<PsiDocComment> {
}
@Override
protected @Nullable <T extends SettingsInfo> String refDoc(@NotNull T lineInfo, @NotNull PsiElement ref) {
protected @Nullable String refDoc(@NotNull LineInfo lineInfo, @NotNull PsiElement ref) {
if ("Override".equals(ref.getText())) {
@Nullable PsiMethod psiMethod = PsiTreeUtil.getParentOfType(ref, PsiMethod.class);
if (psiMethod == null) {

View File

@@ -42,7 +42,7 @@ public class LineExt {
return null;
}
@NotNull Map<String, Map<String, List<String>>> docMap = ConfCache.docMap(path, name, ext);
@NotNull Map<String, Map<String, List<String>>> treeMap = ConfCache.treeMap(path, name, ext);
@NotNull Map<String, Map<String, List<String>>> treeMap = ConfCache.treeMap(path);
if (docMap.isEmpty() && treeMap.isEmpty()) {
return null;
}

View File

@@ -23,8 +23,7 @@ public class TreeExt {
@Nullable
public static String extDoc(@NotNull VirtualFile file) {
@NotNull Map<String, Map<String, List<String>>> docMap = ConfCache.treeMap(
file.getPath(), file.getName(), file.getPath());
@NotNull Map<String, Map<String, List<String>>> docMap = ConfCache.treeMap(file.getPath());
@NotNull String[] words = {
file.getName(),
file.getNameWithoutExtension(),

View File

@@ -4,8 +4,6 @@ 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;
@@ -23,9 +21,6 @@ import java.util.regex.Pattern;
*/
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";
@@ -63,10 +58,8 @@ public class ConfCache {
}
@NotNull
public static Map<String, Map<String, List<String>>> treeMap(@NotNull String path,
@NotNull String name,
@Nullable String ext) {
return ConfCacheGetUtils.filterPath(TREE_CACHE, path, name, ext);
public static Map<String, Map<String, List<String>>> treeMap(@NotNull String path) {
return ConfCacheGetUtils.filterPath(TREE_CACHE, path);
}
static void clearAll() {
@@ -117,10 +110,10 @@ public class ConfCache {
static void loadAll(@NotNull Project project) {
DumbService.getInstance(project).runReadActionInSmartMode(() ->
ApplicationManager.getApplication().runReadAction(() -> {
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project, EXT);
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project, TsvLoader.EXT);
@NotNull StringBuilder sb = new StringBuilder();
for (@NotNull VirtualFile file : files) {
load(project, file);
load(file);
sb.append(file.getName()).append("\n");
}
if (files.isEmpty()) {
@@ -131,33 +124,26 @@ public class ConfCache {
}));
}
static void loadFile(@Nullable Project project, @NotNull VirtualFile file) {
ApplicationManager.getApplication().runReadAction(() -> ConfCache.load(project, file));
static void loadFile(@NotNull VirtualFile file) {
ApplicationManager.getApplication().runReadAction(() -> ConfCache.load(file));
}
private static void load(@Nullable Project project, @NotNull VirtualFile file) {
if (!ConfCache.EXT.equals(file.getExtension())) {
private static void load(@NotNull VirtualFile file) {
if (!TsvLoader.EXT.equals(file.getExtension())) {
return;
}
@Nullable Document document = FileDocumentManager.getInstance().getDocument(file);
if (document == null) {
return;
}
@NotNull String text = document.getText();
@NotNull String name = file.getNameWithoutExtension();
// this pattern would skip empty line
String[] lines = LINE_PATTERN.split(text);
if (name.endsWith(KEY_MID_EXT)) {
@NotNull String matchName = name.substring(0, name.length() - KEY_MID_EXT.length());
int i = matchName.lastIndexOf(".");
if (i > 0) {
EXT_IN_KEY_CACHE.add(matchName.substring(i + 1));
}
KEY_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, true));
KEY_CACHE.put(file, TsvLoader.buildMap(file, true));
} else if (name.endsWith(DOC_MID_EXT)) {
DOC_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, false));
DOC_CACHE.put(file, TsvLoader.buildMap(file, false));
} else if (name.endsWith(TREE_MID_EXT)) {
TREE_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, false));
TREE_CACHE.put(file, TsvLoader.buildMap(file, false));
}
}
}

View File

@@ -6,9 +6,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
class ConfCacheGetUtils {
public class ConfCacheGetUtils {
private static final String SKIP_PATH = "doc";
private static final String MATCH_STR = "%";
@@ -73,9 +74,7 @@ class ConfCacheGetUtils {
* @return {@code <sortKey, T>}
*/
@NotNull
static <T> TreeMap<String, T> filterPath(@SuppressWarnings("SameParameterValue")
@NotNull Map<VirtualFile, T> cache,
@NotNull String path, String name, String ext) {
public static <T> SortedMap<String, T> filterPath(@NotNull Map<VirtualFile, T> cache, @NotNull String path) {
@NotNull TreeMap<String, T> map = new TreeMap<>();
int max = path.length();
int length = String.valueOf(max).length();

View File

@@ -1,16 +1,13 @@
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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -68,30 +65,4 @@ class ConfFactory {
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) {
@NotNull Map<String, List<String>> map = new LinkedHashMap<>();
for (@NotNull String line : lines) {
@NotNull 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);
}
}
return map;
}
}

View File

@@ -18,7 +18,7 @@ public class ConfFileChangeListener implements FileEditorManagerListener {
return;
}
if (file.exists()) {
ConfCache.loadFile(event.getManager().getProject(), file);
ConfCache.loadFile(file);
}
}
}

View File

@@ -29,13 +29,13 @@ public class ConfFileListener implements BulkFileListener {
@NotNull VFilePropertyChangeEvent changeEvent = (VFilePropertyChangeEvent) event;
if ("name".equals(changeEvent.getPropertyName())) {
String oldName = changeEvent.getOldValue().toString();
if (oldName.endsWith(ConfCache.EXT)) {
if (oldName.endsWith(TsvLoader.EXT)) {
// change cache too complicated so remove
ConfCache.remove(file, oldName);
}
}
}
if (!ConfCache.EXT.equals(file.getExtension())) {
if (!TsvLoader.EXT.equals(file.getExtension())) {
return;
}
if (event instanceof VFileMoveEvent) {
@@ -60,6 +60,6 @@ public class ConfFileListener implements BulkFileListener {
}
// VFileCreateEvent
// VFileContentChangeEvent
ConfCache.loadFile(null, file);
ConfCache.loadFile(file);
}
}

View File

@@ -0,0 +1,54 @@
package io.github.linwancen.plugin.show.ext.conf;
import com.google.common.base.Splitter;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.vfs.VirtualFile;
import groovy.json.StringEscapeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class TsvLoader {
private TsvLoader() {}
public static final String EXT = "tsv";
private static final Pattern LINE_PATTERN = Pattern.compile("[\\r\\n]++");
public static final Pattern DEL_PATTERN = Pattern.compile("\\(\\?[^)]++\\)");
@NotNull
public static Map<String, List<String>> buildMap(@NotNull VirtualFile file, boolean patternKey) {
@Nullable Document document = FileDocumentManager.getInstance().getDocument(file);
if (document == null) {
return Collections.emptyMap();
}
@NotNull String text = document.getText();
// this pattern would skip empty line
String[] lines = LINE_PATTERN.split(text);
@NotNull Map<String, List<String>> map = new LinkedHashMap<>();
for (@NotNull String line : lines) {
@NotNull List<String> words = Splitter.on('\t').splitToList(line);
if (!words.isEmpty()) {
String key = words.get(0);
if (key.length() == 0) {
continue;
}
if (patternKey) {
key = StringEscapeUtils.unescapeJava(key);
String del = DEL_PATTERN.matcher(key).replaceAll("");
if (del.length() != 0) {
key = del;
}
}
map.put(key, words);
}
}
return map;
}
}

View File

@@ -1,14 +1,24 @@
package io.github.linwancen.plugin.show.lang;
import com.intellij.json.psi.JsonArray;
import com.intellij.json.psi.JsonObject;
import com.intellij.json.psi.JsonProperty;
import com.intellij.json.psi.JsonValue;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import io.github.linwancen.plugin.show.bean.SettingsInfo;
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import io.github.linwancen.plugin.show.bean.LineInfo;
import io.github.linwancen.plugin.show.ext.conf.ConfCacheGetUtils;
import io.github.linwancen.plugin.show.ext.conf.TsvLoader;
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class JsonLangDoc extends BaseLangDoc {
public static final JsonLangDoc INSTANCE = new JsonLangDoc();
@@ -37,11 +47,15 @@ public class JsonLangDoc extends BaseLangDoc {
}
@Override
protected @Nullable <T extends SettingsInfo> String refDoc(@NotNull T lineInfo, @NotNull PsiElement ref) {
protected @Nullable String refDoc(@NotNull LineInfo lineInfo, @NotNull PsiElement ref) {
if (!(ref instanceof JsonProperty)) {
return null;
}
@NotNull JsonProperty jsonProperty = (JsonProperty) ref;
@Nullable String dictDoc = dictDoc(lineInfo, jsonProperty);
if (dictDoc != null) {
return dictDoc;
}
@NotNull PsiReference[] references = jsonProperty.getNameElement().getReferences();
for (@NotNull PsiReference reference : references) {
@Nullable PsiElement resolve = null;
@@ -60,4 +74,48 @@ public class JsonLangDoc extends BaseLangDoc {
}
return null;
}
@Nullable
private static String dictDoc(@NotNull LineInfo lineInfo, @NotNull JsonProperty prop) {
@Nullable JsonValue value = prop.getValue();
if (value == null || value instanceof JsonArray || value instanceof JsonObject) {
return null;
}
@NotNull GlobalSearchScope scope = GlobalSearchScope.allScope(lineInfo.project);
String jsonKey = prop.getName();
String jsonValue = value.getText();
// Read the json.path before if needed
return jsonDictDoc(lineInfo, scope, jsonKey, jsonValue);
}
@Nullable
private static String jsonDictDoc(@NotNull LineInfo lineInfo, @NotNull GlobalSearchScope scope, String fileName, String jsonValue) {
@NotNull Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(lineInfo.project, fileName + ".tsv", scope);
// one file
if (files.size() < 2) {
for (@NotNull VirtualFile file : files) {
@NotNull Map<String, List<String>> map = TsvLoader.buildMap(file, false);
List<String> list = map.get(jsonValue);
if (list != null && list.size() > 1) {
return list.get(1);
}
}
return null;
}
// multi file
@NotNull Map<VirtualFile, Map<String, List<String>>> fileMap = new ConcurrentHashMap<>();
for (@NotNull VirtualFile file : files) {
@NotNull Map<String, List<String>> map = TsvLoader.buildMap(file, false);
fileMap.put(file, map);
}
@NotNull String path = lineInfo.file.getPath();
@NotNull SortedMap<String, Map<String, List<String>>> treeMap = ConfCacheGetUtils.filterPath(fileMap, path);
for (@NotNull Map.Entry<String, Map<String, List<String>>> entry : treeMap.entrySet()) {
List<String> list = entry.getValue().get(jsonValue);
if (list != null && list.size() > 1) {
return list.get(1);
}
}
return null;
}
}

View File

@@ -5,10 +5,9 @@ import com.intellij.psi.PsiElement;
import com.intellij.sql.psi.SqlLanguage;
import com.intellij.sql.psi.SqlReferenceExpression;
import com.intellij.util.containers.JBIterable;
import io.github.linwancen.plugin.show.bean.SettingsInfo;
import io.github.linwancen.plugin.show.bean.LineInfo;
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
import io.github.linwancen.plugin.show.lang.base.DocSkip;
import io.github.linwancen.plugin.show.bean.LineInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,8 +31,8 @@ public class SqlLangDoc extends BaseLangDoc {
@Override
protected @Nullable <T extends SettingsInfo> String refElementDoc(@NotNull T lineInfo,
@NotNull PsiElement ref) {
protected @Nullable String refElementDoc(@NotNull LineInfo lineInfo,
@NotNull PsiElement ref) {
JBIterable<DbElement> relatedDbElements;
Class<?> clazz;
try {
@@ -48,7 +47,7 @@ public class SqlLangDoc extends BaseLangDoc {
}
}
try {
Method method = clazz.getMethod("findRelatedDbElements", PsiElement.class, boolean.class);
@NotNull Method method = clazz.getMethod("findRelatedDbElements", PsiElement.class, boolean.class);
//noinspection unchecked
relatedDbElements = (JBIterable<DbElement>) method.invoke(null, ref, false);
} catch (Throwable e) {

View File

@@ -116,8 +116,8 @@ public abstract class BaseLangDoc extends EditorLinePainter {
* Override like SQL
*/
@Nullable
protected <T extends SettingsInfo> String refElementDoc(@NotNull T lineInfo,
@NotNull PsiElement refElement) {
protected String refElementDoc(@NotNull LineInfo lineInfo,
@NotNull PsiElement refElement) {
@Nullable String refDoc = refDoc(lineInfo, refElement);
if (refDoc != null && !DocSkip.skipDoc(lineInfo.appSettings, lineInfo.projectSettings, refDoc)) {
return refDoc;
@@ -129,7 +129,7 @@ public abstract class BaseLangDoc extends EditorLinePainter {
* Override like Java/Json
*/
@Nullable
protected <T extends SettingsInfo> String refDoc(@NotNull T lineInfo, @NotNull PsiElement ref) {
protected String refDoc(@NotNull LineInfo lineInfo, @NotNull PsiElement ref) {
// kotlin ref.getReference() == null but ref.getReferences().length == 2
@NotNull PsiReference[] references = ref.getReferences();
if (references.length < 1) {

View File

@@ -55,6 +55,7 @@ Show doc comment at the Project view Tree, line End, json etc.
<!-- please see https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html
on how to target different products -->
<depends>com.intellij.modules.platform</depends>
<depends optional="true" config-file="java.xml">com.intellij.modules.java</depends>
<depends optional="true" config-file="sql.xml">com.intellij.database</depends>
<depends optional="true" config-file="js.xml">JavaScript</depends>

View File

@@ -3,6 +3,7 @@ package io.github.linwancen.plugin.show.demo.json;
import java.util.Date;
import java.util.List;
@SuppressWarnings("all")
public class Pojo {
/** integer */
private int integer;
@@ -15,7 +16,7 @@ public class Pojo {
/** nestedClass */
private NestedClass nestedClass;
/** nestedClassArr */
private NestedClass[] nestedClassArr;
private NestedClass[][] nestedClassArr;
/** nestedClassList */
private List<NestedClass> nestedClassList;

View File

@@ -2,13 +2,17 @@
"nestedClassArr": [
{
"nestedClass2": {
"a": ""
"a": "",
"dict": 0
}
},
{
"nestedClass2": {
"a": ""
[
{
"nestedClass2": {
"a": "",
"dict": 1
}
}
}
]
]
}

View File

@@ -2,5 +2,6 @@
"integer": 0,
"str": "",
"date": "2022-03-04 21:34:01",
"bool": false
"bool": false,
"dict": 0
}

View File

@@ -0,0 +1,2 @@
0 dict_0
1 dict_1
1 0 dict_0
2 1 dict_1

View File

@@ -2,12 +2,14 @@
"nestedClassList": [
{
"nestedClass2": {
"a": ""
"a": "",
"dict": 0
}
},
{
"nestedClass2": {
"a": ""
"a": "",
"dict": 1
}
}
]

View File

@@ -1,7 +1,9 @@
{
"nestedClass": {
"nestedClass2": {
"a": ""
}
"a": "",
"dict": 0
},
"dict": 1
}
}