diff --git a/CHANGELOG.md b/CHANGELOG.md index 433f444f04a3c2b2a9fac893f2b0db4e2f7dff96..dfcf9aa63280420b1c20deb670d1f3695736e323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Solon Changelog +## [0.0.5-M1] +### Added +- Fix various types of conversion exceptions +- Yaml code prompts for adding comments +- Optimize yaml code tips + + ## [0.0.4] ### Added - adjust ui diff --git a/build.gradle.kts b/build.gradle.kts index 0a797988260a2a2c4f9799265e299e79e33982d6..24cda46c6298b39dacf293cb3306f2bd0cf1e336 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { implementation("com.alibaba.fastjson2:fastjson2:2.0.34") // https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 implementation("org.apache.commons:commons-collections4:4.4") + implementation("org.yaml:snakeyaml:2.0") } // Set the JVM language level used to build the project. Use Java 11 for 2020.3+, and Java 17 for 2022.2+. diff --git a/gradle.properties b/gradle.properties index 6f10ac5ddf0a2de76e29a9c026daef50f289a63a..b3a394fdee87805935f2d23f9dd2f7006a4107b4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ pluginName = Solon pluginRepositoryUrl = https://gitee.com/noear/solon-idea-plugin # SemVer format -> https://semver.org -pluginVersion = 0.0.4 +pluginVersion = 0.0.5-M1 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 213 diff --git a/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionContributor.java b/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionContributor.java index 7e55c6cffbb7ebbe190873d24de472145b495181..abd5360f8567c0f9e209890a7cfc30ed4e0b32df 100644 --- a/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionContributor.java +++ b/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionContributor.java @@ -6,8 +6,11 @@ import com.intellij.lang.properties.PropertiesLanguage; import com.intellij.patterns.PlatformPatterns; import org.jetbrains.yaml.YAMLLanguage; -public class YamlCompletionContributor extends CompletionContributor { +import java.util.HashMap; +import java.util.Map; +public class YamlCompletionContributor extends CompletionContributor { + public static Map> yamlMapCache=new HashMap(); public YamlCompletionContributor() { extend( CompletionType.BASIC, diff --git a/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionProvider.java b/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionProvider.java index 0c8b73910b24bc1ee184ec090786c7032edffe2a..df5622effc0f74f2cb81b244d1d3d61e577e4fdb 100644 --- a/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionProvider.java +++ b/src/main/java/org/noear/solon/idea/plugin/suggestion/completion/YamlCompletionProvider.java @@ -4,27 +4,86 @@ import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.psi.YAMLKeyValue; -import org.jetbrains.yaml.psi.impl.YAMLKeyValueImpl; +import org.jetbrains.yaml.psi.impl.YAMLBlockMappingImpl; import org.jetbrains.yaml.psi.impl.YAMLPlainTextImpl; import org.noear.solon.idea.plugin.common.util.GenericUtil; +import org.noear.solon.idea.plugin.suggestion.filetype.SolonYamlFileType; import org.noear.solon.idea.plugin.suggestion.service.SuggestionService; +import org.yaml.snakeyaml.Yaml; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; -public class YamlCompletionProvider extends CompletionProvider { +public class YamlCompletionProvider extends CompletionProvider implements FileEditorManagerListener { - private final String SUB_OPTION="."; + private final String SUB_OPTION = "."; private SuggestionService suggestionService; + private DocumentListener yamlDocumentListener; + @Override + public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + // 检查文件是否是 YAML 文件 + if (file.getFileType().getName().equalsIgnoreCase(SolonYamlFileType.INSTANCE.getName())) { + // 这里可以执行你的逻辑,当打开 YAML 文件时触发 + System.out.println("YAML file opened: " + file.getName()); + FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); + Document document = fileDocumentManager.getDocument(file); + assert document != null; + String text = document.getText(); + try{ + Yaml yaml = new Yaml(); + Map yamlMap = yaml.load(text); + YamlCompletionContributor.yamlMapCache.put(file.getName(),yamlMap); + }catch (RuntimeException ignored){ + + } + yamlDocumentListener=new DocumentListener() { + @Override + public void documentChanged(@NotNull DocumentEvent event) { + DocumentListener.super.documentChanged(event); + String text = event.getDocument().getText(); + try{ + Yaml yaml = new Yaml(); + Map yamlMap = yaml.load(text); + YamlCompletionContributor.yamlMapCache.put(file.getName(),yamlMap); + }catch (RuntimeException ignored){ + + } + } + }; + document.addDocumentListener(yamlDocumentListener); + } + } + + @Override + public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + // 检查文件是否是 YAML 文件 + if (file.getFileType().getName().equalsIgnoreCase(SolonYamlFileType.INSTANCE.getName())) { + // 这里可以执行你的逻辑,当打开 YAML 文件时触发 + System.out.println("YAML file opened: " + file.getName()); + FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); + Document document = fileDocumentManager.getDocument(file); + assert document != null; + YamlCompletionContributor.yamlMapCache.remove(file.getName()); + document.removeDocumentListener(yamlDocumentListener); + } + } + @Override protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement element = parameters.getPosition(); @@ -43,17 +102,17 @@ public class YamlCompletionProvider extends CompletionProvider elementBuilders = new ArrayList<>(); String yamlKey = getYamlKey(yaml); - if (yaml.getParent().getClass() == YAMLKeyValueImpl.class) { - elementBuilders = suggestionService.findHintSuggestionsForQueryPrefix(yamlKey, queryWithDotDelimitedPrefixes); - } else{ - yamlKey = (StringUtils.isEmpty(yamlKey)?yamlKey:yamlKey+SUB_OPTION); - queryWithDotDelimitedPrefixes=queryWithDotDelimitedPrefixes.equals(SUB_OPTION)?yamlKey:yamlKey+queryWithDotDelimitedPrefixes; + if (queryWithDotDelimitedPrefixes.contains(".") || (yaml.getParent() != null && yaml.getParent().getClass() == YAMLBlockMappingImpl.class)) { + yamlKey = (StringUtils.isEmpty(yamlKey) ? yamlKey : yamlKey + SUB_OPTION); + queryWithDotDelimitedPrefixes = queryWithDotDelimitedPrefixes.equals(SUB_OPTION) ? yamlKey : yamlKey + queryWithDotDelimitedPrefixes; elementBuilders = suggestionService.findYamlSuggestionsForQueryPrefix(queryWithDotDelimitedPrefixes); + } else { + elementBuilders = suggestionService.findHintSuggestionsForQueryPrefix(yamlKey, queryWithDotDelimitedPrefixes); } elementBuilders.forEach(resultSet::addElement); } - private SuggestionService getService(PsiElement element){ + private SuggestionService getService(PsiElement element) { return Optional.ofNullable(suggestionService).orElseGet(() -> { Project project = element.getProject(); SuggestionService suggestionService = SuggestionService.getInstance(project); @@ -62,10 +121,13 @@ public class YamlCompletionProvider extends CompletionProvider keys = new ArrayList<>(); PsiElement parent = yamlPlainText.getParent(); - StringBuffer yamlKey=new StringBuffer(); + StringBuffer yamlKey = new StringBuffer(); while (parent != null) { if (parent instanceof YAMLKeyValue) { YAMLKeyValue keyValue = (YAMLKeyValue) parent; @@ -74,17 +136,17 @@ public class YamlCompletionProvider extends CompletionProvider= 0; i--) { + for (int i = keys.size() - 1; i >= 0; i--) { yamlKey.append(keys.get(i)); - if(i!=0){ + if (i != 0) { yamlKey.append(":"); } } - return yamlKey.toString().replace(":","."); + return yamlKey.toString().replace(":", "."); } private T getParentOfType(PsiElement element, Class clazz) { @@ -92,6 +154,6 @@ public class YamlCompletionProvider extends CompletionProvider 1; + boolean lastDot = queryWithDotDelimitedPrefixes.length() == queryWithDotDelimitedPrefixes.lastIndexOf(".") + 1; +/* boolean queryNotEmpty = queryWithDotDelimitedPrefixes.length() > 1; int queryLength = queryNotEmpty ? (queryWithDotDelimitedPrefixes.length() - 1) : queryWithDotDelimitedPrefixes.length(); - String query = lastDot? + String query = lastDot ? queryWithDotDelimitedPrefixes.substring(0, queryLength) : queryWithDotDelimitedPrefixes; - String supplementText = text.substring(lastDot?query.length():query.length()-1); - supplementText=supplementText.indexOf(".")==0?supplementText.substring(1):supplementText; - String[] count = supplementText.split(DELIMITER); + String supplementText = text.substring(lastDot ? query.length() : query.length() - 1); + supplementText = supplementText.indexOf(".") == 0 ? supplementText.substring(1) : supplementText;*/ + String[] supplementTextArr = text.split(DELIMITER); StringBuffer resultText = new StringBuffer(); - for (int i = 0; i < count.length; i++) { - resultText.append(count[i]); + String[] prefixArr = queryWithDotDelimitedPrefixes.split(DELIMITER); + Map stringStringMap = YamlCompletionContributor.yamlMapCache.get(context.getFile().getName()); + for (int i = 0; i < supplementTextArr.length; i++) { + if (stringStringMap != null && i < prefixArr.length && stringStringMap.get(prefixArr[i]) != null) { + stringStringMap = (Map) stringStringMap.get(prefixArr[i]); + continue; + } +// if(i + + +