diff --git a/CHANGELOG.md b/CHANGELOG.md index b5cbaef..d087cee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,26 @@ # easy-i18n Changelog ## [Unreleased] +### THANKS FOR OVER 1000 DOWNLOADS SO FAR! + +### Added +- Basic support for json array values +- Settings option to opt-out code assistance inside editor +- Support key completion and annotation for Kotlin language +- Example locale files for all configuration options +- Donation links on GitHub to support development + +### Changed +- Update dependencies +- Migrate gradle build script + ## [1.3.0] ### Added - Scroll to created / edited translation inside Tree-/Table-View - Support for working with multiple projects at once ### Changed -- Updated dependencies +- Update dependencies - Load translations even if ui tool window is not opened ### Fixed @@ -28,7 +41,7 @@ - Support for IntelliJ 2021.1 ### Changed -- Updated dependencies +- Update dependencies ### Fixed - Exception during i18n key completion / annotation diff --git a/README.md b/README.md index 61966d5..5dd8911 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ![Build](https://github.com/marhali/easy-i18n/workflows/Build/badge.svg) [![Version](https://img.shields.io/jetbrains/plugin/v/16316.svg)](https://plugins.jetbrains.com/plugin/16316) [![Downloads](https://img.shields.io/jetbrains/plugin/d/16316.svg)](https://plugins.jetbrains.com/plugin/16316) +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/marhalide) This is an easy plugin to manage internationalization for JSON or Resource-Bundle(Properties) based locale files. @@ -48,6 +49,11 @@ Most common use case is for translating Webapps or simple Java Applications. Tra - Select the created directory (optional: define the preferred locale to view) and press Ok - Translations can now be created / edited or deleted +Examples for the configuration can be found in the [/example](https://github.com/marhali/easy-i18n/tree/main/example) folder. + +## Donation +If the project helps you to reduce development time, you can give me a [cup of coffee](https://paypal.me/marhalide) :) + --- Plugin based on the [IntelliJ Platform Plugin Template][template]. diff --git a/build.gradle.kts b/build.gradle.kts index 70290e9..e817fcc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,4 @@ import io.gitlab.arturbosch.detekt.Detekt -import org.jetbrains.changelog.closure import org.jetbrains.changelog.markdownToHTML import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -11,7 +10,7 @@ plugins { // Kotlin support id("org.jetbrains.kotlin.jvm") version "1.5.10" // gradle-intellij-plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin - id("org.jetbrains.intellij") version "0.7.3" + id("org.jetbrains.intellij") version "1.0" // gradle-changelog-plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin id("org.jetbrains.changelog") version "1.1.2" // detekt linter - read more: https://detekt.github.io/detekt/gradle.html @@ -26,7 +25,6 @@ version = properties("pluginVersion") // Configure project's dependencies repositories { mavenCentral() - jcenter() } dependencies { detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.17.1") @@ -35,14 +33,14 @@ dependencies { // Configure gradle-intellij-plugin plugin. // Read more: https://github.com/JetBrains/gradle-intellij-plugin intellij { - pluginName = properties("pluginName") - version = properties("platformVersion") - type = properties("platformType") - downloadSources = properties("platformDownloadSources").toBoolean() - updateSinceUntilBuild = true + pluginName.set(properties("pluginName")) + version.set(properties("platformVersion")) + type.set(properties("platformType")) + downloadSources.set(properties("platformDownloadSources").toBoolean()) + updateSinceUntilBuild.set(true) // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. - setPlugins(*properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty).toTypedArray()) + plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty)) } // Configure gradle-changelog-plugin plugin. @@ -80,43 +78,37 @@ tasks { } patchPluginXml { - version(properties("pluginVersion")) - sinceBuild(properties("pluginSinceBuild")) - untilBuild(properties("pluginUntilBuild")) + version.set(properties("pluginVersion")) + sinceBuild.set(properties("pluginSinceBuild")) + untilBuild.set(properties("pluginUntilBuild")) // Extract the section from README.md and provide for the plugin's manifest - pluginDescription( - closure { - File("./README.md").readText().lines().run { - val start = "" - val end = "" + pluginDescription.set( + File(projectDir, "README.md").readText().lines().run { + val start = "" + val end = "" - if (!containsAll(listOf(start, end))) { - throw GradleException("Plugin description section not found in README.md:\n$start ... $end") - } - subList(indexOf(start) + 1, indexOf(end)) - }.joinToString("\n").run { markdownToHTML(this) } - } + if (!containsAll(listOf(start, end))) { + throw GradleException("Plugin description section not found in README.md:\n$start ... $end") + } + subList(indexOf(start) + 1, indexOf(end)) + }.joinToString("\n").run { markdownToHTML(this) } ) // Get the latest available change notes from the changelog file - changeNotes( - closure { - changelog.getLatest().toHTML() - } - ) + changeNotes.set(provider { changelog.getLatest().toHTML() }) } runPluginVerifier { - ideVersions(properties("pluginVerifierIdeVersions")) + ideVersions.set(properties("pluginVerifierIdeVersions").split(',').map(String::trim).filter(String::isNotEmpty)) } publishPlugin { dependsOn("patchChangelog") - token(System.getenv("PUBLISH_TOKEN")) + token.set(System.getenv("PUBLISH_TOKEN")) // pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel - channels(properties("pluginVersion").split('-').getOrElse(1) { "default" }.split('.').first()) + channels.set(listOf(properties("pluginVersion").split('-').getOrElse(1) { "default" }.split('.').first())) } } diff --git a/example/json/locale-de.json b/example/json/locale-de.json new file mode 100644 index 0000000..d5507f9 --- /dev/null +++ b/example/json/locale-de.json @@ -0,0 +1,26 @@ +{ + "alpha": { + "first": "Beispiel Übersetzung", + "second": "Andere Übersetzung" + }, + "beta": { + "title": "Ein Titel", + "nested": { + "title": "Ein verschachtelter Titel" + } + }, + "gamma": { + "title": "Gamma Titel", + "array": { + "simple": [ + "Erstes Element", + "Zweites Element" + ], + "escaped": [ + "Erstes;Element", + "Zweites Element", + "Drittes;Element" + ] + } + } +} \ No newline at end of file diff --git a/example/json/locale-en.json b/example/json/locale-en.json new file mode 100644 index 0000000..b680645 --- /dev/null +++ b/example/json/locale-en.json @@ -0,0 +1,26 @@ +{ + "alpha": { + "first": "example translation", + "second": "another translation" + }, + "beta": { + "title": "some title", + "nested": { + "title": "some nested title" + } + }, + "gamma": { + "title": "gamma title", + "array": { + "simple": [ + "first element", + "second element" + ], + "escaped": [ + "first;element", + "second element", + "third;element" + ] + } + } +} \ No newline at end of file diff --git a/example/modularized-json/locale-de/account.json b/example/modularized-json/locale-de/account.json new file mode 100644 index 0000000..bcec282 --- /dev/null +++ b/example/modularized-json/locale-de/account.json @@ -0,0 +1,5 @@ +{ + "subscription": "Abonnement", + "support": "Unterstützung", + "delete": "Löschen" +} \ No newline at end of file diff --git a/example/modularized-json/locale-de/auth.json b/example/modularized-json/locale-de/auth.json new file mode 100644 index 0000000..e9476c0 --- /dev/null +++ b/example/modularized-json/locale-de/auth.json @@ -0,0 +1,10 @@ +{ + "title": [ + "Ein", + "array", + "Titel" + ], + "login": "Einloggen", + "logout": "Ausloggen", + "register": "Registrieren" +} \ No newline at end of file diff --git a/example/modularized-json/locale-de/user.json b/example/modularized-json/locale-de/user.json new file mode 100644 index 0000000..46bde56 --- /dev/null +++ b/example/modularized-json/locale-de/user.json @@ -0,0 +1,10 @@ +{ + "username": "Benutzername", + "email": "Email-Adresse", + "address": { + "zip": "Postleitzahl", + "city": "Ort", + "street": "Straße", + "number": "Hausnummer" + } +} \ No newline at end of file diff --git a/example/modularized-json/locale-en/account.json b/example/modularized-json/locale-en/account.json new file mode 100644 index 0000000..8f23bb1 --- /dev/null +++ b/example/modularized-json/locale-en/account.json @@ -0,0 +1,5 @@ +{ + "subscription": "Subscription", + "support": "Support", + "delete": "Delete" +} \ No newline at end of file diff --git a/example/modularized-json/locale-en/auth.json b/example/modularized-json/locale-en/auth.json new file mode 100644 index 0000000..5e7ff0d --- /dev/null +++ b/example/modularized-json/locale-en/auth.json @@ -0,0 +1,10 @@ +{ + "title": [ + "Some", + "array", + "title" + ], + "login": "Login", + "logout": "Logout", + "register": "Register" +} \ No newline at end of file diff --git a/example/modularized-json/locale-en/user.json b/example/modularized-json/locale-en/user.json new file mode 100644 index 0000000..6f2f670 --- /dev/null +++ b/example/modularized-json/locale-en/user.json @@ -0,0 +1,10 @@ +{ + "username": "Username", + "email": "Email Address", + "address": { + "zip": "ZIP code", + "city": "City", + "street": "Street", + "number": "House number" + } +} \ No newline at end of file diff --git a/example/resource-bundle/locale_de.properties b/example/resource-bundle/locale_de.properties new file mode 100644 index 0000000..f7c80e7 --- /dev/null +++ b/example/resource-bundle/locale_de.properties @@ -0,0 +1,6 @@ +account.subscription=Abonnement +auth.login=Einloggen +auth.logout=Ausloggen +auth.register=Registrieren +user.email=Email-Adresse +user.username=Benutzername \ No newline at end of file diff --git a/example/resource-bundle/locale_en.properties b/example/resource-bundle/locale_en.properties new file mode 100644 index 0000000..ca60875 --- /dev/null +++ b/example/resource-bundle/locale_en.properties @@ -0,0 +1,6 @@ +account.subscription=Subscription +auth.login=Login +auth.logout=Logout +auth.register=Register +user.email=Email Address +user.username=Username \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 795629b..67ea370 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,19 +3,19 @@ pluginGroup = de.marhali.easyi18n pluginName = easy-i18n -pluginVersion = 1.3.0 +pluginVersion = 1.4.0 pluginSinceBuild = 202 pluginUntilBuild = 211.* # Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl # See https://jb.gg/intellij-platform-builds-list for available build versions -pluginVerifierIdeVersions = 2020.2.4, 2020.3.2, 2021.1 +pluginVerifierIdeVersions = 2020.2.4, 2020.3.4, 2021.1.1 platformType = IC -platformVersion = 2021.1 +platformVersion = 2021.1.3 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 = +platformPlugins = org.jetbrains.kotlin # Opt-out flag for bundling Kotlin standard library. # See https://kotlinlang.org/docs/reference/using-gradle.html#dependency-on-the-standard-library for details. diff --git a/src/main/java/de/marhali/easyi18n/TranslatorToolWindowFactory.java b/src/main/java/de/marhali/easyi18n/TranslatorToolWindowFactory.java index 281419f..161d4b4 100644 --- a/src/main/java/de/marhali/easyi18n/TranslatorToolWindowFactory.java +++ b/src/main/java/de/marhali/easyi18n/TranslatorToolWindowFactory.java @@ -9,9 +9,9 @@ import com.intellij.ui.content.ContentFactory; import de.marhali.easyi18n.service.DataStore; import de.marhali.easyi18n.service.WindowManager; -import de.marhali.easyi18n.ui.action.*; -import de.marhali.easyi18n.ui.tabs.TableView; -import de.marhali.easyi18n.ui.tabs.TreeView; +import de.marhali.easyi18n.action.*; +import de.marhali.easyi18n.tabs.TableView; +import de.marhali.easyi18n.tabs.TreeView; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/de/marhali/easyi18n/ui/action/AddAction.java b/src/main/java/de/marhali/easyi18n/action/AddAction.java similarity index 94% rename from src/main/java/de/marhali/easyi18n/ui/action/AddAction.java rename to src/main/java/de/marhali/easyi18n/action/AddAction.java index 317b971..20f9dba 100644 --- a/src/main/java/de/marhali/easyi18n/ui/action/AddAction.java +++ b/src/main/java/de/marhali/easyi18n/action/AddAction.java @@ -1,11 +1,11 @@ -package de.marhali.easyi18n.ui.action; +package de.marhali.easyi18n.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import de.marhali.easyi18n.service.WindowManager; -import de.marhali.easyi18n.ui.dialog.AddDialog; +import de.marhali.easyi18n.dialog.AddDialog; import de.marhali.easyi18n.util.TreeUtil; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/de/marhali/easyi18n/ui/action/ReloadAction.java b/src/main/java/de/marhali/easyi18n/action/ReloadAction.java similarity index 94% rename from src/main/java/de/marhali/easyi18n/ui/action/ReloadAction.java rename to src/main/java/de/marhali/easyi18n/action/ReloadAction.java index ed7ac40..5930963 100644 --- a/src/main/java/de/marhali/easyi18n/ui/action/ReloadAction.java +++ b/src/main/java/de/marhali/easyi18n/action/ReloadAction.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.action; +package de.marhali.easyi18n.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; diff --git a/src/main/java/de/marhali/easyi18n/ui/action/SearchAction.java b/src/main/java/de/marhali/easyi18n/action/SearchAction.java similarity index 98% rename from src/main/java/de/marhali/easyi18n/ui/action/SearchAction.java rename to src/main/java/de/marhali/easyi18n/action/SearchAction.java index 123a615..42b16c7 100644 --- a/src/main/java/de/marhali/easyi18n/ui/action/SearchAction.java +++ b/src/main/java/de/marhali/easyi18n/action/SearchAction.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.action; +package de.marhali.easyi18n.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; diff --git a/src/main/java/de/marhali/easyi18n/ui/action/SettingsAction.java b/src/main/java/de/marhali/easyi18n/action/SettingsAction.java similarity index 87% rename from src/main/java/de/marhali/easyi18n/ui/action/SettingsAction.java rename to src/main/java/de/marhali/easyi18n/action/SettingsAction.java index 6bd209d..42feefa 100644 --- a/src/main/java/de/marhali/easyi18n/ui/action/SettingsAction.java +++ b/src/main/java/de/marhali/easyi18n/action/SettingsAction.java @@ -1,9 +1,9 @@ -package de.marhali.easyi18n.ui.action; +package de.marhali.easyi18n.action; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import de.marhali.easyi18n.ui.dialog.SettingsDialog; +import de.marhali.easyi18n.dialog.SettingsDialog; import org.jetbrains.annotations.NotNull; import java.util.ResourceBundle; diff --git a/src/main/java/de/marhali/easyi18n/ui/action/treeview/CollapseTreeViewAction.java b/src/main/java/de/marhali/easyi18n/action/treeview/CollapseTreeViewAction.java similarity index 94% rename from src/main/java/de/marhali/easyi18n/ui/action/treeview/CollapseTreeViewAction.java rename to src/main/java/de/marhali/easyi18n/action/treeview/CollapseTreeViewAction.java index 0d33a4e..a8390c3 100644 --- a/src/main/java/de/marhali/easyi18n/ui/action/treeview/CollapseTreeViewAction.java +++ b/src/main/java/de/marhali/easyi18n/action/treeview/CollapseTreeViewAction.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.action.treeview; +package de.marhali.easyi18n.action.treeview; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; diff --git a/src/main/java/de/marhali/easyi18n/ui/action/treeview/ExpandTreeViewAction.java b/src/main/java/de/marhali/easyi18n/action/treeview/ExpandTreeViewAction.java similarity index 94% rename from src/main/java/de/marhali/easyi18n/ui/action/treeview/ExpandTreeViewAction.java rename to src/main/java/de/marhali/easyi18n/action/treeview/ExpandTreeViewAction.java index 915e7b4..0e07c9e 100644 --- a/src/main/java/de/marhali/easyi18n/ui/action/treeview/ExpandTreeViewAction.java +++ b/src/main/java/de/marhali/easyi18n/action/treeview/ExpandTreeViewAction.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.action.treeview; +package de.marhali.easyi18n.action.treeview; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; diff --git a/src/main/java/de/marhali/easyi18n/ui/dialog/AddDialog.java b/src/main/java/de/marhali/easyi18n/dialog/AddDialog.java similarity index 98% rename from src/main/java/de/marhali/easyi18n/ui/dialog/AddDialog.java rename to src/main/java/de/marhali/easyi18n/dialog/AddDialog.java index 12527f9..8a50820 100644 --- a/src/main/java/de/marhali/easyi18n/ui/dialog/AddDialog.java +++ b/src/main/java/de/marhali/easyi18n/dialog/AddDialog.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.dialog; +package de.marhali.easyi18n.dialog; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; diff --git a/src/main/java/de/marhali/easyi18n/ui/dialog/EditDialog.java b/src/main/java/de/marhali/easyi18n/dialog/EditDialog.java similarity index 96% rename from src/main/java/de/marhali/easyi18n/ui/dialog/EditDialog.java rename to src/main/java/de/marhali/easyi18n/dialog/EditDialog.java index 00884eb..09f3e21 100644 --- a/src/main/java/de/marhali/easyi18n/ui/dialog/EditDialog.java +++ b/src/main/java/de/marhali/easyi18n/dialog/EditDialog.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.dialog; +package de.marhali.easyi18n.dialog; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; @@ -10,7 +10,7 @@ import de.marhali.easyi18n.service.DataStore; import de.marhali.easyi18n.model.KeyedTranslation; import de.marhali.easyi18n.model.TranslationDelete; import de.marhali.easyi18n.model.TranslationUpdate; -import de.marhali.easyi18n.ui.dialog.descriptor.DeleteActionDescriptor; +import de.marhali.easyi18n.dialog.descriptor.DeleteActionDescriptor; import javax.swing.*; import javax.swing.border.EtchedBorder; diff --git a/src/main/java/de/marhali/easyi18n/ui/dialog/SettingsDialog.java b/src/main/java/de/marhali/easyi18n/dialog/SettingsDialog.java similarity index 80% rename from src/main/java/de/marhali/easyi18n/ui/dialog/SettingsDialog.java rename to src/main/java/de/marhali/easyi18n/dialog/SettingsDialog.java index eeafe30..fc1eb92 100644 --- a/src/main/java/de/marhali/easyi18n/ui/dialog/SettingsDialog.java +++ b/src/main/java/de/marhali/easyi18n/dialog/SettingsDialog.java @@ -1,10 +1,11 @@ -package de.marhali.easyi18n.ui.dialog; +package de.marhali.easyi18n.dialog; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBTextField; @@ -26,6 +27,7 @@ public class SettingsDialog { private TextFieldWithBrowseButton pathText; private JBTextField filePatternText; private JBTextField previewText; + private JBCheckBox codeAssistanceCheckbox; public SettingsDialog(Project project) { this.project = project; @@ -35,18 +37,20 @@ public class SettingsDialog { String localesPath = SettingsService.getInstance(project).getState().getLocalesPath(); String filePattern = SettingsService.getInstance(project).getState().getFilePattern(); String previewLocale = SettingsService.getInstance(project).getState().getPreviewLocale(); + boolean codeAssistance = SettingsService.getInstance(project).getState().isCodeAssistance(); - if(prepare(localesPath, filePattern, previewLocale).show() == DialogWrapper.OK_EXIT_CODE) { // Save changes + if(prepare(localesPath, filePattern, previewLocale, codeAssistance).show() == DialogWrapper.OK_EXIT_CODE) { // Save changes SettingsService.getInstance(project).getState().setLocalesPath(pathText.getText()); SettingsService.getInstance(project).getState().setFilePattern(filePatternText.getText()); SettingsService.getInstance(project).getState().setPreviewLocale(previewText.getText()); + SettingsService.getInstance(project).getState().setCodeAssistance(codeAssistanceCheckbox.isSelected()); // Reload instance DataStore.getInstance(project).reloadFromDisk(); } } - private DialogBuilder prepare(String localesPath, String filePattern, String previewLocale) { + private DialogBuilder prepare(String localesPath, String filePattern, String previewLocale, boolean codeAssistance) { JPanel rootPanel = new JPanel(new GridLayout(0, 1, 2, 2)); JBLabel pathLabel = new JBLabel(ResourceBundle.getBundle("messages").getString("settings.path.text")); @@ -73,6 +77,11 @@ public class SettingsDialog { rootPanel.add(previewLabel); rootPanel.add(previewText); + codeAssistanceCheckbox = new JBCheckBox(ResourceBundle.getBundle("messages").getString("settings.editor.assistance")); + codeAssistanceCheckbox.setSelected(codeAssistance); + + rootPanel.add(codeAssistanceCheckbox); + DialogBuilder builder = new DialogBuilder(); builder.setTitle(ResourceBundle.getBundle("messages").getString("action.settings")); builder.removeAllActions(); diff --git a/src/main/java/de/marhali/easyi18n/ui/dialog/descriptor/DeleteActionDescriptor.java b/src/main/java/de/marhali/easyi18n/dialog/descriptor/DeleteActionDescriptor.java similarity index 95% rename from src/main/java/de/marhali/easyi18n/ui/dialog/descriptor/DeleteActionDescriptor.java rename to src/main/java/de/marhali/easyi18n/dialog/descriptor/DeleteActionDescriptor.java index a1cd61e..3460601 100644 --- a/src/main/java/de/marhali/easyi18n/ui/dialog/descriptor/DeleteActionDescriptor.java +++ b/src/main/java/de/marhali/easyi18n/dialog/descriptor/DeleteActionDescriptor.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.dialog.descriptor; +package de.marhali.easyi18n.dialog.descriptor; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; diff --git a/src/main/java/de/marhali/easyi18n/ui/editor/I18nKeyAnnotator.java b/src/main/java/de/marhali/easyi18n/editor/KeyAnnotator.java similarity index 55% rename from src/main/java/de/marhali/easyi18n/ui/editor/I18nKeyAnnotator.java rename to src/main/java/de/marhali/easyi18n/editor/KeyAnnotator.java index 481288e..3395133 100644 --- a/src/main/java/de/marhali/easyi18n/ui/editor/I18nKeyAnnotator.java +++ b/src/main/java/de/marhali/easyi18n/editor/KeyAnnotator.java @@ -1,11 +1,8 @@ -package de.marhali.easyi18n.ui.editor; +package de.marhali.easyi18n.editor; import com.intellij.lang.annotation.AnnotationHolder; -import com.intellij.lang.annotation.Annotator; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiLiteralValue; import de.marhali.easyi18n.model.LocalizedNode; import de.marhali.easyi18n.service.DataStore; @@ -14,28 +11,25 @@ import de.marhali.easyi18n.service.SettingsService; import org.jetbrains.annotations.NotNull; /** - * Translation key annotator. + * Superclass for managing key annotations. * @author marhali */ -public class I18nKeyAnnotator implements Annotator { +public class KeyAnnotator { - @Override - public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { - if(!(element instanceof PsiLiteralValue)) { + /** + * Adds annotations for i18n keys with content preview for preferred locale. + * @param key I18n key extracted by psi element + * @param project Project instance + * @param holder Annotation holder + */ + protected void annotate(@NotNull String key, @NotNull Project project, @NotNull AnnotationHolder holder) { + // Do not annotate keys if service is disabled + if(!SettingsService.getInstance(project).getState().isCodeAssistance()) { return; } - PsiLiteralValue literalValue = (PsiLiteralValue) element; - String value = literalValue.getValue() instanceof String ? (String) literalValue.getValue() : null; - - if(value == null) { - return; - } - - Project project = element.getProject(); String previewLocale = SettingsService.getInstance(project).getState().getPreviewLocale(); - - LocalizedNode node = DataStore.getInstance(project).getTranslations().getNode(value); + LocalizedNode node = DataStore.getInstance(project).getTranslations().getNode(key); if(node == null) { // Unknown translation. Just ignore it return; diff --git a/src/main/java/de/marhali/easyi18n/ui/editor/I18nCompletionProvider.java b/src/main/java/de/marhali/easyi18n/editor/KeyCompletionProvider.java similarity index 85% rename from src/main/java/de/marhali/easyi18n/ui/editor/I18nCompletionProvider.java rename to src/main/java/de/marhali/easyi18n/editor/KeyCompletionProvider.java index bc77b00..27633aa 100644 --- a/src/main/java/de/marhali/easyi18n/ui/editor/I18nCompletionProvider.java +++ b/src/main/java/de/marhali/easyi18n/editor/KeyCompletionProvider.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.editor; +package de.marhali.easyi18n.editor; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; @@ -20,11 +20,19 @@ import java.util.List; * I18n translation key completion provider. * @author marhali */ -public class I18nCompletionProvider extends CompletionProvider { +public class KeyCompletionProvider extends CompletionProvider { @Override - protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) { + protected void addCompletions(@NotNull CompletionParameters parameters, + @NotNull ProcessingContext context, @NotNull CompletionResultSet result) { + Project project = parameters.getOriginalFile().getProject(); + + // Do not annotate keys if service is disabled + if(!SettingsService.getInstance(project).getState().isCodeAssistance()) { + return; + } + String previewLocale = SettingsService.getInstance(project).getState().getPreviewLocale(); String query = result.getPrefixMatcher().getPrefix(); diff --git a/src/main/java/de/marhali/easyi18n/editor/generic/GenericKeyAnnotator.java b/src/main/java/de/marhali/easyi18n/editor/generic/GenericKeyAnnotator.java new file mode 100644 index 0000000..8de8149 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/editor/generic/GenericKeyAnnotator.java @@ -0,0 +1,33 @@ +package de.marhali.easyi18n.editor.generic; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralValue; + +import de.marhali.easyi18n.editor.KeyAnnotator; + +import org.jetbrains.annotations.NotNull; + +/** + * Translation key annotator for generic languages which support {@link PsiLiteralValue}. + * @author marhali + */ +public class GenericKeyAnnotator extends KeyAnnotator implements Annotator { + + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + if(!(element instanceof PsiLiteralValue)) { + return; + } + + PsiLiteralValue literalValue = (PsiLiteralValue) element; + String value = literalValue.getValue() instanceof String ? (String) literalValue.getValue() : null; + + if(value == null) { + return; + } + + annotate(value, element.getProject(), holder); + } +} \ No newline at end of file diff --git a/src/main/java/de/marhali/easyi18n/editor/generic/GenericKeyCompletionContributor.java b/src/main/java/de/marhali/easyi18n/editor/generic/GenericKeyCompletionContributor.java new file mode 100644 index 0000000..e84b7ec --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/editor/generic/GenericKeyCompletionContributor.java @@ -0,0 +1,19 @@ +package de.marhali.easyi18n.editor.generic; + +import com.intellij.codeInsight.completion.CompletionContributor; +import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.patterns.*; +import com.intellij.psi.PsiLiteralValue; +import de.marhali.easyi18n.editor.KeyCompletionProvider; + +/** + * Translation key completion for generic languages which support {@link PsiLiteralValue}. + * @author marhali + */ +public class GenericKeyCompletionContributor extends CompletionContributor { + + public GenericKeyCompletionContributor() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement().inside(PsiLiteralValue.class), + new KeyCompletionProvider()); + } +} \ No newline at end of file diff --git a/src/main/java/de/marhali/easyi18n/editor/kotlin/KotlinKeyAnnotator.java b/src/main/java/de/marhali/easyi18n/editor/kotlin/KotlinKeyAnnotator.java new file mode 100644 index 0000000..4e9cfe3 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/editor/kotlin/KotlinKeyAnnotator.java @@ -0,0 +1,31 @@ +package de.marhali.easyi18n.editor.kotlin; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.psi.PsiElement; + +import de.marhali.easyi18n.editor.KeyAnnotator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry; + +/** + * Kotlin specific translation key annotator + * @author marhali + */ +public class KotlinKeyAnnotator extends KeyAnnotator implements Annotator { + + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + if(!(element instanceof KtLiteralStringTemplateEntry)) { + return; + } + + String value = element.getText(); + + if(value == null) { + return; + } + + annotate(value, element.getProject(), holder); + } +} \ No newline at end of file diff --git a/src/main/java/de/marhali/easyi18n/editor/kotlin/KotlinKeyCompletionContributor.java b/src/main/java/de/marhali/easyi18n/editor/kotlin/KotlinKeyCompletionContributor.java new file mode 100644 index 0000000..30a6a57 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/editor/kotlin/KotlinKeyCompletionContributor.java @@ -0,0 +1,20 @@ +package de.marhali.easyi18n.editor.kotlin; + +import com.intellij.codeInsight.completion.CompletionContributor; +import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.patterns.PlatformPatterns; + +import de.marhali.easyi18n.editor.KeyCompletionProvider; +import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry; + +/** + * Kotlin specific translation key completion contributor. + * @author marhali + */ +public class KotlinKeyCompletionContributor extends CompletionContributor { + + public KotlinKeyCompletionContributor() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement().inside(KtLiteralStringTemplateEntry.class), + new KeyCompletionProvider()); + } +} diff --git a/src/main/java/de/marhali/easyi18n/ui/listener/DeleteKeyListener.java b/src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java similarity index 93% rename from src/main/java/de/marhali/easyi18n/ui/listener/DeleteKeyListener.java rename to src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java index 283976d..2c45b1f 100644 --- a/src/main/java/de/marhali/easyi18n/ui/listener/DeleteKeyListener.java +++ b/src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.listener; +package de.marhali.easyi18n.listener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; diff --git a/src/main/java/de/marhali/easyi18n/ui/listener/PopupClickListener.java b/src/main/java/de/marhali/easyi18n/listener/PopupClickListener.java similarity index 95% rename from src/main/java/de/marhali/easyi18n/ui/listener/PopupClickListener.java rename to src/main/java/de/marhali/easyi18n/listener/PopupClickListener.java index 4d2845f..585b39d 100644 --- a/src/main/java/de/marhali/easyi18n/ui/listener/PopupClickListener.java +++ b/src/main/java/de/marhali/easyi18n/listener/PopupClickListener.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.listener; +package de.marhali.easyi18n.listener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; diff --git a/src/main/java/de/marhali/easyi18n/model/SettingsState.java b/src/main/java/de/marhali/easyi18n/model/SettingsState.java index be0b0f2..ba2dfb8 100644 --- a/src/main/java/de/marhali/easyi18n/model/SettingsState.java +++ b/src/main/java/de/marhali/easyi18n/model/SettingsState.java @@ -11,10 +11,12 @@ public class SettingsState { public static final String DEFAULT_PREVIEW_LOCALE = "en"; public static final String DEFAULT_FILE_PATTERN = ".*"; + public static final boolean DEFAULT_CODE_ASSISTANCE = true; private String localesPath; private String filePattern; private String previewLocale; + private Boolean codeAssistance; public SettingsState() {} @@ -41,4 +43,12 @@ public class SettingsState { public void setPreviewLocale(String previewLocale) { this.previewLocale = previewLocale; } + + public boolean isCodeAssistance() { + return codeAssistance == null ? DEFAULT_CODE_ASSISTANCE : codeAssistance; + } + + public void setCodeAssistance(boolean codeAssistance) { + this.codeAssistance = codeAssistance; + } } \ No newline at end of file diff --git a/src/main/java/de/marhali/easyi18n/ui/renderer/TableRenderer.java b/src/main/java/de/marhali/easyi18n/renderer/TableRenderer.java similarity index 96% rename from src/main/java/de/marhali/easyi18n/ui/renderer/TableRenderer.java rename to src/main/java/de/marhali/easyi18n/renderer/TableRenderer.java index 18aeab4..cebe4c9 100644 --- a/src/main/java/de/marhali/easyi18n/ui/renderer/TableRenderer.java +++ b/src/main/java/de/marhali/easyi18n/renderer/TableRenderer.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.renderer; +package de.marhali.easyi18n.renderer; import com.intellij.ui.JBColor; diff --git a/src/main/java/de/marhali/easyi18n/ui/renderer/TreeRenderer.java b/src/main/java/de/marhali/easyi18n/renderer/TreeRenderer.java similarity index 86% rename from src/main/java/de/marhali/easyi18n/ui/renderer/TreeRenderer.java rename to src/main/java/de/marhali/easyi18n/renderer/TreeRenderer.java index b8ae3c5..f643dd7 100644 --- a/src/main/java/de/marhali/easyi18n/ui/renderer/TreeRenderer.java +++ b/src/main/java/de/marhali/easyi18n/renderer/TreeRenderer.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.renderer; +package de.marhali.easyi18n.renderer; import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.navigation.ItemPresentation; @@ -7,9 +7,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.TreeCellRenderer; -import java.awt.*; /** * Similar to {@link NodeRenderer} but will will override {@link #getPresentation(Object)} to diff --git a/src/main/java/de/marhali/easyi18n/service/WindowManager.java b/src/main/java/de/marhali/easyi18n/service/WindowManager.java index cf4d632..c92883e 100644 --- a/src/main/java/de/marhali/easyi18n/service/WindowManager.java +++ b/src/main/java/de/marhali/easyi18n/service/WindowManager.java @@ -2,8 +2,8 @@ package de.marhali.easyi18n.service; import com.intellij.openapi.wm.ToolWindow; -import de.marhali.easyi18n.ui.tabs.TableView; -import de.marhali.easyi18n.ui.tabs.TreeView; +import de.marhali.easyi18n.tabs.TableView; +import de.marhali.easyi18n.tabs.TreeView; public class WindowManager { diff --git a/src/main/java/de/marhali/easyi18n/ui/tabs/TableView.form b/src/main/java/de/marhali/easyi18n/tabs/TableView.form similarity index 93% rename from src/main/java/de/marhali/easyi18n/ui/tabs/TableView.form rename to src/main/java/de/marhali/easyi18n/tabs/TableView.form index e88ccbb..51d35af 100644 --- a/src/main/java/de/marhali/easyi18n/ui/tabs/TableView.form +++ b/src/main/java/de/marhali/easyi18n/tabs/TableView.form @@ -1,5 +1,5 @@ -
+ diff --git a/src/main/java/de/marhali/easyi18n/ui/tabs/TableView.java b/src/main/java/de/marhali/easyi18n/tabs/TableView.java similarity index 92% rename from src/main/java/de/marhali/easyi18n/ui/tabs/TableView.java rename to src/main/java/de/marhali/easyi18n/tabs/TableView.java index 5e81cc1..4b7dc31 100644 --- a/src/main/java/de/marhali/easyi18n/ui/tabs/TableView.java +++ b/src/main/java/de/marhali/easyi18n/tabs/TableView.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.tabs; +package de.marhali.easyi18n.tabs; import com.intellij.openapi.project.Project; import com.intellij.ui.components.JBScrollPane; @@ -11,10 +11,10 @@ import de.marhali.easyi18n.model.Translations; import de.marhali.easyi18n.model.KeyedTranslation; import de.marhali.easyi18n.model.TranslationDelete; import de.marhali.easyi18n.model.table.TableModelTranslator; -import de.marhali.easyi18n.ui.dialog.EditDialog; -import de.marhali.easyi18n.ui.listener.DeleteKeyListener; -import de.marhali.easyi18n.ui.listener.PopupClickListener; -import de.marhali.easyi18n.ui.renderer.TableRenderer; +import de.marhali.easyi18n.dialog.EditDialog; +import de.marhali.easyi18n.listener.DeleteKeyListener; +import de.marhali.easyi18n.listener.PopupClickListener; +import de.marhali.easyi18n.renderer.TableRenderer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/de/marhali/easyi18n/ui/tabs/TreeView.form b/src/main/java/de/marhali/easyi18n/tabs/TreeView.form similarity index 94% rename from src/main/java/de/marhali/easyi18n/ui/tabs/TreeView.form rename to src/main/java/de/marhali/easyi18n/tabs/TreeView.form index de99827..053a09b 100644 --- a/src/main/java/de/marhali/easyi18n/ui/tabs/TreeView.form +++ b/src/main/java/de/marhali/easyi18n/tabs/TreeView.form @@ -1,5 +1,5 @@ - + diff --git a/src/main/java/de/marhali/easyi18n/ui/tabs/TreeView.java b/src/main/java/de/marhali/easyi18n/tabs/TreeView.java similarity index 90% rename from src/main/java/de/marhali/easyi18n/ui/tabs/TreeView.java rename to src/main/java/de/marhali/easyi18n/tabs/TreeView.java index a4b77cd..069f975 100644 --- a/src/main/java/de/marhali/easyi18n/ui/tabs/TreeView.java +++ b/src/main/java/de/marhali/easyi18n/tabs/TreeView.java @@ -1,4 +1,4 @@ -package de.marhali.easyi18n.ui.tabs; +package de.marhali.easyi18n.tabs; import com.intellij.ide.projectView.PresentationData; import com.intellij.openapi.actionSystem.ActionManager; @@ -14,13 +14,12 @@ import de.marhali.easyi18n.model.Translations; import de.marhali.easyi18n.model.KeyedTranslation; import de.marhali.easyi18n.model.TranslationDelete; import de.marhali.easyi18n.model.tree.TreeModelTranslator; -import de.marhali.easyi18n.ui.action.treeview.CollapseTreeViewAction; -import de.marhali.easyi18n.ui.action.treeview.ExpandTreeViewAction; -import de.marhali.easyi18n.ui.dialog.EditDialog; -import de.marhali.easyi18n.ui.listener.DeleteKeyListener; -import de.marhali.easyi18n.ui.listener.PopupClickListener; -import de.marhali.easyi18n.ui.renderer.TreeRenderer; -import de.marhali.easyi18n.util.TranslationsUtil; +import de.marhali.easyi18n.action.treeview.CollapseTreeViewAction; +import de.marhali.easyi18n.action.treeview.ExpandTreeViewAction; +import de.marhali.easyi18n.dialog.EditDialog; +import de.marhali.easyi18n.listener.DeleteKeyListener; +import de.marhali.easyi18n.listener.PopupClickListener; +import de.marhali.easyi18n.renderer.TreeRenderer; import de.marhali.easyi18n.util.TreeUtil; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/de/marhali/easyi18n/ui/editor/I18nCompletionContributor.java b/src/main/java/de/marhali/easyi18n/ui/editor/I18nCompletionContributor.java deleted file mode 100644 index fce0ae2..0000000 --- a/src/main/java/de/marhali/easyi18n/ui/editor/I18nCompletionContributor.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.marhali.easyi18n.ui.editor; - -import com.intellij.codeInsight.completion.CompletionContributor; -import com.intellij.codeInsight.completion.CompletionType; -import com.intellij.patterns.*; -import com.intellij.psi.PsiLiteralValue; - -/** - * Show i18n key completion for literal values. - * @author marhali - */ -public class I18nCompletionContributor extends CompletionContributor { - - public I18nCompletionContributor() { - extend(CompletionType.BASIC, PlatformPatterns.psiElement().inside(PsiLiteralValue.class), - new I18nCompletionProvider()); - } -} \ No newline at end of file diff --git a/src/main/java/de/marhali/easyi18n/util/JsonArrayUtil.java b/src/main/java/de/marhali/easyi18n/util/JsonArrayUtil.java new file mode 100644 index 0000000..c1a73e0 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/util/JsonArrayUtil.java @@ -0,0 +1,51 @@ +package de.marhali.easyi18n.util; + +import com.google.gson.JsonArray; +import org.apache.commons.lang.StringEscapeUtils; + +import java.util.regex.Pattern; + +/** + * Utility methods to read and write json arrays. + * @author marhali + */ +public class JsonArrayUtil { + + public static String ARRAY_PREFIX = "!arr["; + public static String ARRAY_SUFFIX = "]"; + public static char ARRAY_DELIMITER = ';'; + + public static String read(JsonArray array) { + StringBuilder builder = new StringBuilder(ARRAY_PREFIX); + + for(int i = 0; i < array.size(); i++) { + if(i > 0) { + builder.append(ARRAY_DELIMITER); + } + + String value = array.get(i).getAsString().replace(";", "\\;"); + builder.append(StringUtil.escapeControls(value, true)); + } + + builder.append(ARRAY_SUFFIX); + return builder.toString(); + } + + public static JsonArray write(String concat) { + concat = concat.substring(ARRAY_PREFIX.length(), concat.length() - ARRAY_SUFFIX.length()); + String regex = "(? messages = leafNode.getValue(); - String value = StringUtil.escapeControls(entry.getValue().getAsString(), true); + + String value = entry.getValue().isJsonArray() + ? JsonArrayUtil.read(entry.getValue().getAsJsonArray()) + : StringUtil.escapeControls(entry.getValue().getAsString(), true); + messages.put(locale, value); leafNode.setValue(messages); } diff --git a/src/main/resources/META-INF/de.marhali.easyi18n-kotlin.xml b/src/main/resources/META-INF/de.marhali.easyi18n-kotlin.xml new file mode 100644 index 0000000..441c647 --- /dev/null +++ b/src/main/resources/META-INF/de.marhali.easyi18n-kotlin.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 483a1ba..a452e0e 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -5,15 +5,17 @@ + com.intellij.modules.platform com.intellij.modules.lang + org.jetbrains.kotlin + implementationClass="de.marhali.easyi18n.editor.generic.GenericKeyCompletionContributor" /> - + \ No newline at end of file diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 0c12843..727cd4f 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -14,4 +14,5 @@ translation.locales=Locales settings.path.title=Locales Directory settings.path.text=Locales directory settings.path.file-pattern=Translation file pattern -settings.preview=Preview locale \ No newline at end of file +settings.preview=Preview locale +settings.editor.assistance=I18n key completion and annotation inside editor \ No newline at end of file