Skip to content

Commit

Permalink
feat: Add storefront snippet autocompletion
Browse files Browse the repository at this point in the history
  • Loading branch information
shyim committed Sep 21, 2021
1 parent 7632e09 commit 80e8884
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 1 deletion.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 = ""
Expand Down
Original file line number Diff line number Diff line change
@@ -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<CompletionParameters>() {
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))
}
}
}
)
}
}
50 changes: 50 additions & 0 deletions src/main/kotlin/de/shyim/shopware6/index/FrontendSnippetIndex.kt
Original file line number Diff line number Diff line change
@@ -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<String, Set<String>>() {
override fun getName(): ID<String, Set<String>> {
return key
}

override fun getVersion(): Int {
return 1
}

override fun dependsOnFileContent(): Boolean {
return true
}

override fun getIndexer(): DataIndexer<String, Set<String>, 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<String> {
return EnumeratorStringDescriptor.INSTANCE
}

override fun getValueExternalizer(): DataExternalizer<Set<String>> {
return StringSetDataExternalizer.INSTANCE
}

companion object {
val key = ID.create<String, Set<String>>("de.shyim.shopware6.frontend.snippet")
}

override fun getInputFilter(): FileBasedIndex.InputFilter {
return object : DefaultFileTypeSpecificInputFilter(JsonFileType.INSTANCE) {
}
}
}
40 changes: 40 additions & 0 deletions src/main/kotlin/de/shyim/shopware6/util/SnippetUtil.kt
Original file line number Diff line number Diff line change
@@ -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<String, Set<String>> {
val content = THashMap<String, Set<String>>()
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<String, Set<String>>, 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) {
}
}
}
33 changes: 33 additions & 0 deletions src/main/kotlin/de/shyim/shopware6/util/TwigPattern.kt
Original file line number Diff line number Diff line change
@@ -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<PsiElement?> {
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)
}
}
5 changes: 5 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<depends>com.intellij.modules.platform</depends>
<depends>com.jetbrains.php</depends>
<depends>com.jetbrains.twig</depends>
<depends>JavaScript</depends>
<depends>Git4Idea</depends>

Expand All @@ -16,6 +17,10 @@
<defaultLiveTemplates file="/liveTemplates/Shopware 6 PHPUnit.xml"/>

<fileTemplateGroup implementation="de.shyim.shopware6.templates.ShopwareTemplates"/>
<fileBasedIndex implementation="de.shyim.shopware6.index.FrontendSnippetIndex"/>

<completion.contributor language="Twig"
implementationClass="de.shyim.shopware6.completion.TwigCompletionProvider"/>
</extensions>

<actions>
Expand Down

0 comments on commit 80e8884

Please sign in to comment.