From 80e88849ba9788d75e87a29b2271dffea2a13af0 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Tue, 21 Sep 2021 23:06:16 +0200 Subject: [PATCH] feat: Add storefront snippet autocompletion --- gradle.properties | 2 +- .../action/generator/NewChangelogAction.kt | 6 +++ .../completion/TwigCompletionProvider.kt | 32 ++++++++++++ .../shopware6/index/FrontendSnippetIndex.kt | 50 +++++++++++++++++++ .../de/shyim/shopware6/util/SnippetUtil.kt | 40 +++++++++++++++ .../de/shyim/shopware6/util/TwigPattern.kt | 33 ++++++++++++ src/main/resources/META-INF/plugin.xml | 5 ++ 7 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/de/shyim/shopware6/completion/TwigCompletionProvider.kt create mode 100644 src/main/kotlin/de/shyim/shopware6/index/FrontendSnippetIndex.kt create mode 100644 src/main/kotlin/de/shyim/shopware6/util/SnippetUtil.kt create mode 100644 src/main/kotlin/de/shyim/shopware6/util/TwigPattern.kt diff --git a/gradle.properties b/gradle.properties index 5bdb351..c11dcf7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ platformDownloadSources = true # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 -platformPlugins=com.jetbrains.php:212.4746.100,JavaScriptLanguage,Git4Idea +platformPlugins=com.jetbrains.php:212.4746.100,com.jetbrains.twig:212.4746.2,JavaScriptLanguage,Git4Idea # Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3 javaVersion = 11 diff --git a/src/main/kotlin/de/shyim/shopware6/action/generator/NewChangelogAction.kt b/src/main/kotlin/de/shyim/shopware6/action/generator/NewChangelogAction.kt index 4994a66..c48cf4f 100644 --- a/src/main/kotlin/de/shyim/shopware6/action/generator/NewChangelogAction.kt +++ b/src/main/kotlin/de/shyim/shopware6/action/generator/NewChangelogAction.kt @@ -4,7 +4,9 @@ import com.intellij.icons.AllIcons import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.fileTypes.PlainTextFileType import com.intellij.openapi.project.DumbAwareAction +import com.intellij.util.indexing.FileBasedIndex import de.shyim.shopware6.action.generator.ui.NewChangelogDialogWrapper +import de.shyim.shopware6.index.FrontendSnippetIndex import de.shyim.shopware6.templates.ShopwareTemplates import git4idea.branch.GitBranchUtil import org.apache.commons.lang.StringUtils @@ -17,6 +19,10 @@ class NewChangelogAction: DumbAwareAction("Create a Changelog", "Create a new Ch return } + val index = FileBasedIndex.getInstance() + println(index.getAllKeys(FrontendSnippetIndex.key, e.project!!)); + + val currentBranch = GitBranchUtil.getCurrentRepository(e.project!!)?.currentBranch var defaultTitle = "" var defaultTicket = "" diff --git a/src/main/kotlin/de/shyim/shopware6/completion/TwigCompletionProvider.kt b/src/main/kotlin/de/shyim/shopware6/completion/TwigCompletionProvider.kt new file mode 100644 index 0000000..284dbf3 --- /dev/null +++ b/src/main/kotlin/de/shyim/shopware6/completion/TwigCompletionProvider.kt @@ -0,0 +1,32 @@ +package de.shyim.shopware6.completion + +import com.intellij.codeInsight.completion.* +import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.openapi.project.Project +import com.intellij.util.ProcessingContext +import com.intellij.util.indexing.FileBasedIndex +import de.shyim.shopware6.index.FrontendSnippetIndex +import de.shyim.shopware6.util.TwigPattern +import icons.ShopwareToolBoxIcons + + +class TwigCompletionProvider() : CompletionContributor() { + init { + extend( + CompletionType.BASIC, + TwigPattern.getTranslationKeyPattern("trans", "transchoice"), + object : CompletionProvider() { + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet + ) { + val project: Project = parameters.position.project + for (key in FileBasedIndex.getInstance().getAllKeys(FrontendSnippetIndex.key, project)) { + result.addElement(LookupElementBuilder.create(key!!).withIcon(ShopwareToolBoxIcons.SHOPWARE)) + } + } + } + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/shyim/shopware6/index/FrontendSnippetIndex.kt b/src/main/kotlin/de/shyim/shopware6/index/FrontendSnippetIndex.kt new file mode 100644 index 0000000..bf26315 --- /dev/null +++ b/src/main/kotlin/de/shyim/shopware6/index/FrontendSnippetIndex.kt @@ -0,0 +1,50 @@ +package de.shyim.shopware6.index + +import com.intellij.json.JsonFileType +import com.intellij.util.indexing.* +import com.intellij.util.io.DataExternalizer +import com.intellij.util.io.EnumeratorStringDescriptor +import com.intellij.util.io.KeyDescriptor +import com.jetbrains.php.lang.psi.stubs.indexes.StringSetDataExternalizer +import de.shyim.shopware6.util.SnippetUtil + +open class FrontendSnippetIndex : FileBasedIndexExtension>() { + override fun getName(): ID> { + return key + } + + override fun getVersion(): Int { + return 1 + } + + override fun dependsOnFileContent(): Boolean { + return true + } + + override fun getIndexer(): DataIndexer, FileContent> { + return DataIndexer { inputData -> + if (!inputData.getFile().getName().equals("storefront.en-GB.json")) { + return@DataIndexer mapOf() + } + + return@DataIndexer SnippetUtil.flatten(inputData.contentAsText.toString()) + } + } + + override fun getKeyDescriptor(): KeyDescriptor { + return EnumeratorStringDescriptor.INSTANCE + } + + override fun getValueExternalizer(): DataExternalizer> { + return StringSetDataExternalizer.INSTANCE + } + + companion object { + val key = ID.create>("de.shyim.shopware6.frontend.snippet") + } + + override fun getInputFilter(): FileBasedIndex.InputFilter { + return object : DefaultFileTypeSpecificInputFilter(JsonFileType.INSTANCE) { + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/shyim/shopware6/util/SnippetUtil.kt b/src/main/kotlin/de/shyim/shopware6/util/SnippetUtil.kt new file mode 100644 index 0000000..a13d30d --- /dev/null +++ b/src/main/kotlin/de/shyim/shopware6/util/SnippetUtil.kt @@ -0,0 +1,40 @@ +package de.shyim.shopware6.util + +import gnu.trove.THashMap +import org.codehaus.jettison.json.JSONException +import org.codehaus.jettison.json.JSONObject + +object SnippetUtil { + fun flatten(fileContent: String?): THashMap> { + val content = THashMap>() + return try { + val jsonObject = JSONObject(fileContent) + val it = jsonObject.keys() + while (it.hasNext()) { + val key = it.next().toString() + flatten(content, jsonObject, key, key) + } + content + } catch (e: JSONException) { + e.printStackTrace() + content + } + } + + private fun flatten(content: THashMap>, json: JSONObject, key: String, prefix: String) { + try { + val jsonObject = json.getJSONObject(key) + val it = jsonObject.keys() + while (it.hasNext()) { + val innerKey = it.next().toString() + flatten(content, jsonObject, innerKey, "$prefix.$innerKey") + } + return + } catch (ignored: JSONException) { + } + try { + content[prefix] = setOf(json.getString(key)) + } catch (ignored: JSONException) { + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/shyim/shopware6/util/TwigPattern.kt b/src/main/kotlin/de/shyim/shopware6/util/TwigPattern.kt new file mode 100644 index 0000000..9f7dceb --- /dev/null +++ b/src/main/kotlin/de/shyim/shopware6/util/TwigPattern.kt @@ -0,0 +1,33 @@ +package de.shyim.shopware6.util + +import com.intellij.patterns.ElementPattern +import com.intellij.patterns.PlatformPatterns +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiWhiteSpace +import com.jetbrains.twig.TwigLanguage +import com.jetbrains.twig.TwigTokenTypes + +object TwigPattern { + fun getTranslationKeyPattern(vararg type: String?): ElementPattern { + return PlatformPatterns + .psiElement(TwigTokenTypes.STRING_TEXT) + .beforeLeafSkipping( + PlatformPatterns.or( + PlatformPatterns.psiElement(PsiWhiteSpace::class.java), + PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE), + PlatformPatterns.psiElement(TwigTokenTypes.SINGLE_QUOTE), + PlatformPatterns.psiElement(TwigTokenTypes.DOUBLE_QUOTE) + ), + PlatformPatterns.psiElement(TwigTokenTypes.FILTER).beforeLeafSkipping( + PlatformPatterns.or( + PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE), + PlatformPatterns.psiElement(PsiWhiteSpace::class.java) + ), + PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).withText( + PlatformPatterns.string().oneOf(*type) + ) + ) + ) + .withLanguage(TwigLanguage.INSTANCE) + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 97c61cf..fb21d41 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -6,6 +6,7 @@ com.intellij.modules.platform com.jetbrains.php + com.jetbrains.twig JavaScript Git4Idea @@ -16,6 +17,10 @@ + + +